home *** CD-ROM | disk | FTP | other *** search
- /* C O P Y R I G H T N O T I C E : */
- /* Copyright 1986 Eric Jul and Norm Hutchinson. May not be used for any */
- /* purpose without written permission from the authors. */
- /* Modifications copyright 1988, 1989 Clinton Jeffery, just for eric */
-
- #include "Kernel/h/system.h"
- #include "Kernel/h/assert.h"
- #include "Kernel/h/macros.h"
- #include "Kernel/h/errMsgs.h"
- #include "Kernel/h/mmCodes.h"
- #include "Kernel/h/emTypes.h"
- #include "Kernel/h/timerTypes.h"
- #include "Kernel/h/kmdTypes.h"
- #include "Kernel/h/kEvents.h"
- #include "Kernel/h/emCodes.h"
- #include "Kernel/h/mmMsgTypes.h"
- #include "Kernel/h/lmTypes.h"
- #include "Kernel/h/emkDefs.h"
- #include "Kernel/h/lmCodes.h"
- #include "Kernel/h/hotsTypes.h"
- #include "Kernel/h/map.h"
- #include "Kernel/h/set.h"
- #include "Kernel/h/consts.h"
- #include "Kernel/h/utils.h"
-
- /*
- * CHECKPOINT support is now integrated into this module-- 7/22/88 cjeffery
- *
- * Throughout the move _delivery_ subsystem, a null LMHandle
- * signifies a Checkpoint operation instead of the usual move.
- * The recovery subsystem typically uses LMHandles as replicantPtrs.
- */
- #define ISCHECKPOINT (!fHandlePtr)
-
- extern int ReturnOffStack; /* Label in assembly code (!) */
- extern void StartProcessAtAddr();
- extern EmLocation thisNodeLocation;
-
- extern int cEmRunnable;
- extern SSPtr removeQ(), preemptRunning(), stoppedQ, readyQ,
- NewStackSegment();
- extern void insertQ(), schedule(), FreeUpMovedStackSegment();
- extern ODTag stdCodeODTag, stdGODTag, stdSSODTag;
- extern void fail(), unavail();
- extern void AddToTTable(), DigestTable(), MoveToTTable(),
- MoveARs(), AddCodeAddrToTTable(),
- MoveVarToTTable(), AddVarToTTable(),
- AddReqToTTable(), TranslateVar();
- extern char *BrandNames[];
- extern Boolean LoadRequest();
- extern void OTInsert(), EnsureRemovedFromInvokeQueue();
- extern ODP OTLookup(), getFreeOD();
- extern Boolean MoveDownStack();
- extern void FindParamSizes();
- extern OID getNextOID();
- extern CodeAddr TranslateCodeAddr();
- extern GenericReqPtr TranslateReq();
- extern EmLocation NewLocation();
- extern void UpdateLocation();
- extern TTMoveCondEntry moveCondEntry;
- extern Map condMap;
- extern void ActivateCond(), DeActivateCond();
- extern void UnblockInitially();
-
- /* Counters from measure.c */
- extern int cMV_MovesDone, cMV_MovesBytesSent;
- extern int cMV_MovesPacketsSent;
-
- /*Forward */
- void FixInvokeQueue();
- void MoveMonitorToTTable();
- void MoveSSODToTTable();
- HResult RecoverCallBack();
- void _realMoveCallBack();
-
- /************************************************************************/
- /* Fixing and unfixing global objects */
- /************************************************************************/
-
- void Fix(fODP, fNewLocation)
- register ODP fODP;
- register ODP fNewLocation;
- /* fix the object pointed to */
- {
- KMDTrace("FixMe", 3, "(Fix me: Fix is not fully implemented) %x %x\n",
- fODP, fNewLocation);
-
- /* if integer or immutable then fail */
- /* if local then fail */
- /* if new location is here then */
- /* if global and resident, set fixed bit */
- /* if global and non-resident, do remote fix */
- /* if new location is NOT here, and object is, then */
- /* call upon move protocol */
- /* if neither location nor object is here then forward req to new
- location */
- }
-
-
- void UnFix(fODP, fNewLocation)
- register ODP fODP;
- register ODP fNewLocation;
- /* unfix the object pointed to */
- {
- KMDTrace("FixMe", 3, "(Fix me: UnFix is not fully implemented) %x %x\n",
- fODP, fNewLocation);
-
- /* if integer or immutable then fail */
- /* if local then fail */
- /* if global and resident, set fixed bit */
- /* if global and non-resident, do remote fix */
- }
-
- void IsFixed(fODP)
- register ODP fODP;
- /* return true iff the object is fixed somewhere */
- {
- KMDTrace("FixMe", 3, "(Fix me: IsFixed is not fully implemented) %x %x\n",
- fODP);
- /* If integer then ??? */
- /* If local then ??? */
- /* If global & resident then check for isFixed */
- /* else forward request */
- currentSSP->resultBrand = DataBrand;
- currentSSP->regs.arg1 = FALSE;
- }
- /**********************************************************************/
- /**********************************************************************/
-
- /**********************************************************************/
- /* TraverseAndMoveARList */
- /**********************************************************************/
-
- void TraverseAndMoveARList(fGODP, fARSet)
- GODP fGODP;
- Set fARSet;
- {
- register InvokeQueuePtr q, head;
- register SSAddr l;
-
- KMDTrace("Move", 4, "Traversing AR list for GODP 0x%06x, %s\n", fGODP,
- PPGOID(fGODP->ownOID));
- head = &fGODP->ARListHead;
- for (q = head->next; q != head; q = q->next) {
- l = mLFromInvokeQueuePtr(q);
- KMDTrace("Move", 5, "Adding l = 0x%06x to ARSet\n", l);
- Set_Insert(fARSet, (int) l);
- }
- }
-
-
-
- /*
- * TraverseAndTranslateDataArea
- *
- * Traverse the data area of the given object and translate it according
- * to the given map.
- */
- void TraverseAndTranslateDataArea(fODP, fMap, isRecovery)
- ODP fODP;
- Map fMap;
- {
- register TemplateEntryPtr t;
- register int i;
- register Bytes *dataAddr;
- CodePtr cPtr;
- TemplatePtr theTemplate;
- char kmdDest[12];
-
- assert(fODP->G.tag.tag == GODataTag || fODP->G.tag.tag == LOTag);
- strcpy(kmdDest,(isRecovery ? "Recover" : "Move"));
-
- /* Translate CodePtr */
- cPtr = (CodePtr) Map_Lookup(fMap, (int) fODP->L.myCodePtr);
-
- KMDTrace(kmdDest, 4, "Translating 0x%04x using code %s\n",
- fODP, PPCodePtr(cPtr));
- KMDTrace(kmdDest, 5, "CodePtr: (0x%05x -> 0x%05x) one of %s\n",
- fODP->L.myCodePtr, cPtr, PPCodePtr(cPtr));
-
- assert(NonNIL(cPtr));
-
- fODP->L.myCodePtr = cPtr;
-
- KMDTrace(kmdDest, 5, "Instance size (from code): %d\n", cPtr->instanceSize);
-
- assert(cPtr->ODATemplateOffset);
-
- theTemplate = (TemplatePtr) addOffset(cPtr, cPtr->ODATemplateOffset);
- KMDTrace(kmdDest, 5, "Number of template entries %d\n",
- theTemplate->B.numEntries);
-
- t = &theTemplate->entry[0];
-
- if (fODP->L.tag.replicated) {
- dataAddr = (Bytes *) &fODP->R.inlineData[0];
- } else dataAddr = (Bytes *) &fODP->L.inlineData[0];
-
- KMDTrace(kmdDest, 5, "Data starts at 0x%05x\n", dataAddr);
- for (i = 0; i < theTemplate->B.numEntries; i++) {
-
- switch (t->TE.SS.Format) {
-
- case ShortStaticF: {
- KMDTrace(kmdDest, 5, "\tShortStaticF\t(%s) %s\tcount =%4d\n",
- BrandNames[(int)t->TE.SS.theBrand],
- t->TE.SS.paramInfo != 0 ? "isParam" : " ",
- t->TE.SS.count);
-
- switch (t->TE.SS.theBrand) {
-
- case DataBrand: {
- register int j;
- for (j = 0; j < t->TE.SS.count; j+=sizeof(int))
- KMDTrace(kmdDest, 5, "%6d: Data: %08x\n",
- (dataAddr + j) - (Bytes *) fODP, * ((int *)(dataAddr + j)));
- dataAddr += (t->TE.SS.count == 1 ? 4: t->TE.SS.count);
- break;
- }
-
- case ODPBrand: {
- register int j;
- register ODP *ODPAddr;
- int oldValue;
-
- for (j = 1; j <= t->TE.SS.count; j++) {
- oldValue = * (int *) dataAddr;
- ODPAddr = (ODP *) dataAddr;
- *ODPAddr = (ODP) Map_Lookup(fMap, (int) oldValue);
- KMDTrace(kmdDest, 5, "%6d: ODP (0x%05x->0x%05x)\n",
- dataAddr - (Bytes *) fODP, oldValue, *ODPAddr);
- dataAddr += sizeof(ODP);
- }
- break;
- }
-
- case AddrBrand:{
- assert(t->TE.SS.theBrand != AddrBrand);
- dataAddr += t->TE.SS.count * sizeof(dataAddr);
- break;
- }
-
- case VectorBrand: {
- register VectorAreaPtr v;
- register int count;
-
- v = (VectorAreaPtr) dataAddr;
- dataAddr = (Bytes *) &v->data[0];
- count = v->count;
-
- KMDTrace(kmdDest, 5, "\t\tElementBrand = %s, count %d\n",
- BrandNames[(int)t->TE.SS.elementBrand], count);
- KMDTrace(kmdDest, 5, "\t\tVector type %s\n",
- PPCOID(fODP->L.myCodePtr->ownOID));
-
- switch (t->TE.SS.elementBrand) {
-
- case DataBrand: {
- /* Do nothing */
- if (fODP->L.myCodePtr->ownOID == (unsigned int) 0xff00008b) {
- /* A real hack but for tracing only ... it is a string */
- KMDTrace(kmdDest, 5, "\t\tString: %.*s\n", count, &v->data[0]);
- }
- dataAddr += count;
- break;
- }
-
- case ODPBrand: {
- register ODP *ODPAddr;
- register int j;
- register ODP oldODP;
- for (j = 0; j < count / sizeof(ODP); j++) {
- ODPAddr = (ODP *) dataAddr;
- oldODP = *ODPAddr;
- *ODPAddr = (ODP) Map_Lookup(fMap, (int) oldODP);
- KMDTrace(kmdDest, 5, "\t\t%6d: ODP (0x%05x) -> (0x%05x) %s\n", j,
- oldODP, *ODPAddr, t->TE.SS.attachedFlag ? " Attached":"");
- dataAddr += sizeof(ODP);
- }
- break;
- }
-
- case VariableBrand:{
- register int j;
- register AVariablePtr varPtr;
- int oldAbCon, oldODP;
-
- for (j = 0; j < count / sizeof(AVariable); j++){
- varPtr = (AVariablePtr) dataAddr;
- oldAbCon = (int) varPtr->myAbConPtr;
- oldODP = (int) varPtr->myAddr;
- TranslateVar(varPtr, fMap);
- KMDTrace(kmdDest, 5,
- "\t\t%6d: Var (0x%01x, 0x%01x) -> (0x%01x, 0x%01x), %s\n",
- j, oldAbCon, oldODP, varPtr->myAddr,
- varPtr->myAbConPtr, PPVar(varPtr));
- dataAddr += sizeof(AVariable);
- }
- break;
- }
-
- default:
- ErrMsg("Bad element brand, %s, in vector - compiler error\n",
- PPBrand(t->TE.SS.elementBrand));
- } /* switch on Vector element brand*/
- break;
- }
-
- case VariableBrand: {
- register int j;
- register AVariablePtr varPtr;
- int oldAbCon, oldODP;
-
- for (j = 1; j <= t->TE.SS.count; j++) {
- varPtr = (AVariablePtr) dataAddr;
- oldAbCon = (int) varPtr->myAbConPtr;
- oldODP = (int) varPtr->myAddr;
- TranslateVar(varPtr, fMap);
- KMDTrace(kmdDest, 5,
- "%6d: Var (0x%01x, 0x%01x) -> (0x%01x, 0x%01x), %s\n",
- dataAddr - (Bytes *)fODP, oldAbCon, oldODP,
- varPtr->myAddr, varPtr->myAbConPtr,
- PPVar(varPtr));
- dataAddr += sizeof(AVariable);
- }
- break;
- }
-
- case MonitorBrand: {
- register MonitorLockPtr mPtr;
- Offset monLockOffset;
- MonitorLockPtr oldmPtr;
- ODP oldODP;
-
- mPtr = (MonitorLockPtr) dataAddr;
- monLockOffset = byteOffset(fODP, dataAddr);
-
- if(isRecovery){ /* was ifndef IGNORENORM */
- mPtr->isLocked = FALSE;
- mPtr->waiting = NULL;
- }
-
- KMDTrace(kmdDest, 5, "%6d: Monitor %s\n", monLockOffset,
- mPtr->isLocked ? "Locked" : "Open");
- /*
- * Enter the address of the monitor lock into the translation
- * table so that Conditions can be translated correctly.
- * Unfortunately, this is not easy since we do not have the
- * original address of the monitorlock. Instead, we have to
- * reconstruct it.
- */
- oldODP = (ODP) Map_InverseLookup(fMap, (int) fODP);
- KMDTrace(kmdDest, 5, "\tOld ODP of 0x%06x is 0x%06x\n", oldODP, fODP);
- assert(NonNIL(oldODP));
- oldmPtr = (MonitorLockPtr) addOffset(oldODP, monLockOffset);
- KMDTrace(kmdDest, 5, "\tmonLock (0x%06x -> 0x%06x) insert\n",
- oldmPtr, mPtr);
- Map_Insert(fMap, (int) oldmPtr, (int) mPtr);
-
- KMDTrace(kmdDest, 5, "Old waiting 0x%06x\n", mPtr->waiting);
- if (NonNULL(mPtr->waiting)) {
- mPtr->waiting = (SSPtr) Map_Lookup(fMap, (int) mPtr->waiting);
- KMDTrace(kmdDest, 5, " --> new waiting 0x%06x\n",mPtr->waiting);
- assert(NonNIL(mPtr->waiting));
- }
- dataAddr += sizeof(MonitorLock);
- break;
- }
-
- default:
- ErrMsg("Bad brand: %s\n", PPBrand(t->TE.SS.theBrand));
- (void) abort();
- } /* switch */
-
- t = (TemplateEntryPtr) addOffset(t, sizeof(ShortStatic));
- break;
- }
-
- case RegisterF:
- KMDTrace(kmdDest, 5, "\tRegisterF\t(%s),\t%s, r%d, count %d\n",
- BrandNames[(int)t->TE.R.theBrand],
- t->TE.R.storedWhere == InRegister ? "InRegister" : "InSaveArea",
- t->TE.R.reg, t->TE.R.count);
- ErrMsg("Registers in data area -- compiler error\n");
- assert(FALSE);
- (void) abort();
- break;
-
- default:
- ErrMsg("Bad template format %d\n", t->TE.SS.Format);
- assert(FALSE);
- (void) abort();
- break;
- } /* switch (t->TE.SS.Format) */
- }
- }
-
- /*
- * TraverseAndMove
- *
- * Traverse the data area of the given object and move any component objects
- * that must follow it (i.e., attached, replicated, or local objects).
- * fODP must point to a data area.
- * fSentMap contains the ODPs already sent -- add the ODP sent to it.
- * fARSet contains the ARs to be sent -- add any new ARs to it.
- */
- void TraverseAndMove(fHandlePtr, fODP, fSentMap, fARSet)
- LMHandle *fHandlePtr;
- ODP fODP;
- Map fSentMap;
- Set fARSet;
- {
- register TemplateEntryPtr t;
- register int i;
- register Bytes *dataAddr;
- register LODataPtr dataPtr;
- CodePtr cPtr;
- TemplatePtr theTemplate;
- char kmddest[12];
-
- strcpy(kmddest,(ISCHECKPOINT?"Checkpoint":"Move"));
-
- dataPtr = (LODataPtr) fODP;
-
- assert(dataPtr->tag.tag == GODataTag || dataPtr->tag.tag == LOTag);
-
- cPtr = fODP->L.myCodePtr;
- assert(NonNIL(cPtr));
- KMDTrace(kmddest, 4, "Sending subcomponents of 0x%04x using code %s\n",
- fODP, PPCodePtr(cPtr));
-
- KMDTrace(kmddest, 5, "Instance size (from code): %d\n", cPtr->instanceSize);
-
- assert(NonNULL(cPtr->ODATemplateOffset));
- theTemplate = (TemplatePtr) addOffset(cPtr, cPtr->ODATemplateOffset);
- KMDTrace(kmddest, 5, "Number of template entries %d\n",
- theTemplate->B.numEntries);
-
- t = &theTemplate->entry[0];
-
- dataAddr =
- (Bytes *)(fODP->L.tag.replicated? fODP->R.inlineData : fODP->L.inlineData);
-
- KMDTrace(kmddest, 5, "Data starts at 0x%05x\n", dataAddr);
- for (i = 0; i < theTemplate->B.numEntries; i++) {
-
- switch (t->TE.SS.Format) {
-
- case ShortStaticF: {
- KMDTrace(kmddest, 5, "\tShortStaticF\t(%s) %s\tcount =%4d\n",
- BrandNames[(int)t->TE.SS.theBrand],
- t->TE.SS.paramInfo != 0 ? "isParam" : " ",
- t->TE.SS.count);
-
- switch (t->TE.SS.theBrand) {
-
- case DataBrand: {
- register int j;
- for (j = 0; j < t->TE.SS.count; j+=sizeof(int))
- KMDTrace(kmddest, 5, "%6d: Data: %08x\n",
- (dataAddr + j) - (Bytes *) fODP, * ((int *)(dataAddr + j)));
- dataAddr += (t->TE.SS.count == 1 ? 4 : t->TE.SS.count);
- break;
- }
-
- case ODPBrand: {
- register int j;
- register ODP *ODPAddr;
-
- for (j = 1; j <= t->TE.SS.count; j++) {
- ODPAddr = (ODP *) dataAddr;
- KMDTrace(kmddest, 5, "%6d: ODP (0x%05x)%s\n",
- dataAddr - (Bytes *) fODP, *ODPAddr,
- t->TE.SS.attachedFlag ? " Attached" : "");
- if (t->TE.SS.attachedFlag) {
- MoveToTTable(fHandlePtr, *ODPAddr, fSentMap, fARSet);
- } else {
- AddToTTable(fHandlePtr, *ODPAddr, fSentMap, fARSet);
- }
- dataAddr += sizeof(ODP);
- }
- break;
- }
-
- case AddrBrand: {
- assert(t->TE.SS.theBrand != AddrBrand);
- dataAddr += t->TE.SS.count * sizeof(dataAddr);
- break;
- }
-
- case VectorBrand: {
- register VectorAreaPtr v;
- register int count;
-
- v = (VectorAreaPtr) dataAddr;
- dataAddr= (Bytes *) v->data;
- count = v->count;
-
- KMDTrace(kmddest, 5, "\t\tElementBrand = %s, count %d\n",
- BrandNames[(int)t->TE.SS.elementBrand], count);
- KMDTrace(kmddest, 5, "\t\tVector type %s\n",
- PPCOID(fODP->L.myCodePtr->ownOID));
-
- switch (t->TE.SS.elementBrand) {
-
- case DataBrand: {
- /* Do nothing */
- if (fODP->L.myCodePtr->ownOID == (unsigned int) 0xff00008b) {
- KMDTrace(kmddest, 5, "\t\tString count %d\n", count);
- KMDTrace(kmddest, 5, "\t\tString: %.*s\n", count, v->data);
- }
- dataAddr += (count == 1 ? 4 : count);
- break;
- }
-
- case ODPBrand: {
- register ODP *ODPAddr;
- register int j;
-
- for (j = 0; j < count / sizeof(ODP); j++) {
- ODPAddr = (ODP *) dataAddr;
- KMDTrace(kmddest, 5, "\t\t%6d: ODP (0x%05x)%s\n",
- j, *ODPAddr, t->TE.SS.attachedFlag ? " Attached" : "");
- if (t->TE.SS.attachedFlag) {
- MoveToTTable(fHandlePtr, *ODPAddr, fSentMap, fARSet);
- } else {
- AddToTTable(fHandlePtr, *ODPAddr, fSentMap, fARSet);
- }
- dataAddr += sizeof(ODP);
- }
- break;
- }
-
- case VariableBrand: {
- register AVariablePtr varPtr;
- register int j;
-
- for (j = 0; j < count / sizeof(AVariable); j++) {
- varPtr = (AVariablePtr) dataAddr;
- KMDTrace(kmddest, 5, "\t\t%6d: Var (0x%01x, 0x%01x), %s%s\n",
- j, varPtr->myAddr, varPtr->myAbConPtr,
- t->TE.SS.attachedFlag ? "Attached " : "", PPVar(varPtr));
- if (t->TE.SS.attachedFlag) {
- MoveVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
- } else {
- AddVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
- }
- dataAddr += sizeof(AVariable);
- }
- break;
- }
-
- default: {
- ErrMsg("Bad element brand, %s, in vector - compiler error\n",
- PPBrand(t->TE.SS.elementBrand));
- (void) abort();
- }
- } /* switch (t->TE.SS.elementBrand) */
- break;
- }
-
- case VariableBrand: {
- register int j;
- register AVariablePtr varPtr;
-
- for (j = 1; j <= t->TE.SS.count; j++){
- varPtr = (AVariablePtr) dataAddr;
- KMDTrace(kmddest, 5, "%6d: Var (0x%01x, 0x%01x), %s%s\n",
- dataAddr-(Bytes *)fODP, varPtr->myAddr, varPtr->myAbConPtr,
- t->TE.SS.attachedFlag ? "Attached " : "", PPVar(varPtr));
- if (t->TE.SS.attachedFlag) {
- MoveVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
- } else {
- AddVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
- }
- dataAddr += sizeof(AVariable);
- }
- break;
- }
-
- case MonitorBrand: {
- register MonitorLockPtr mPtr;
- register SSPtr p;
-
- mPtr = (MonitorLockPtr) dataAddr;
- KMDTrace(kmddest, 5, "%6d: Monitor %s\n",
- dataAddr - (Bytes *) fODP,mPtr->isLocked ? "Locked" : "Open");
- if (NonNULL(mPtr->waiting)) {
- KMDTrace(kmddest, 4, "Processes awaiting entry:\n");
- p = mPtr->waiting;
- do {
- p = getRQLink(p);
- KMDTrace(kmddest, 5, "\t%s in %s\n",
- PPPOID(p->processOID), PPSSPlace(p));
- } while (p != mPtr->waiting);
- }
- if(!ISCHECKPOINT)
- MoveMonitorToTTable(fHandlePtr, mPtr, fSentMap, fARSet);
- dataAddr += sizeof(MonitorLock);
- break;
- }
-
- default:
- KMDTrace(kmddest, 5, "Bad brand, %s, in TraverseAndMove\n",
- PPBrand(t->TE.SS.theBrand));
- (void) abort();
-
-
- } /* end switch (t->TE.SS.theBrand) */
-
- t = (TemplateEntryPtr) addOffset(t, sizeof(ShortStatic));
- break;
- }
-
- case RegisterF: {
- KMDTrace(kmddest, 5, "\tRegisterF\t(%s), %s, reg = %4d, count %d\n",
- PPBrand(t->TE.R.theBrand),
- t->TE.R.storedWhere == InRegister ? "InRegister" : "InSaveArea",
- t->TE.R.reg, t->TE.R.count);
- ErrMsg("Fix me: registers in data area ???\n");
- assert(FALSE);
- (void) abort();
- break;
- }
-
- default:
- KMDTrace(kmddest, 5, "Bad format %d\n", t->TE.SS.Format);
- (void) abort();
- break;
-
- } /* switch (t->TE.SS.Format) */
- } /* for ( ... ) */
- }
-
-
- /*
- * TraverseAndTranslate
- *
- * Traverse the data area of the given object and translate it according
- * to the map given.
- */
- void TraverseAndTranslate(fODP, fMap, isRecovery)
- ODP fODP;
- Map fMap;
- int isRecovery;
- {
- char kmdDest[8];
-
- strcpy(kmdDest,(isRecovery ? "Recover" : "Move"));
- KMDTrace("TT", 5, "TraverseAndTranslate(0x%01x) one of %s\n",
- fODP, PPODTag(fODP->G.tag));
-
- switch (fODP->G.tag.tag) {
-
- case GODTag:
- KMDTrace(kmdDest, 5, "Translate GOD @ %s dataPtr 0x%04x, one of %s\n",
- PPLoc(fODP->G.ownLoc),fODP->G.dataPtr, PPCOID(fODP->G.myCodeOID));
-
- /* Ought to have ARListHead here */
- TraverseAndTranslateDataArea((ODP) fODP->G.dataPtr, fMap, isRecovery);
- if(!isRecovery){
- fODP->G.tag.setUpDone = TRUE;
- fODP->G.tag.frozen = FALSE;
- UnblockInitially((GODP) fODP);
- }
- break;
-
-
- case GODataTag:
- case LOTag: {
- TraverseAndTranslateDataArea(fODP, fMap, isRecovery);
- break;
- }
-
- case CondTag:{
- MonitorLockPtr theNewLock;
- KMDTrace(kmdDest, 5, "Translate Cond %s\n", PPODP(fODP));
- theNewLock = (MonitorLockPtr) Map_Lookup(fMap, (int) fODP->CD.theLock);
-
- KMDTrace(kmdDest, 5, "Lock (0x%06x -> 0x%06x)\n",
- fODP->CD.theLock, theNewLock);
- fODP->CD.theLock = theNewLock;
-
- KMDTrace(kmdDest, 5, "Old waiting: 0x%06x\n", fODP->CD.waiting);
- if (IsNULL(fODP->CD.waiting)) {
- KMDTrace(kmdDest, 5, "No Waiting processes\n");
- } else {
- fODP->CD.waiting = (isRecovery ? 0 :
- (SSPtr) Map_Lookup(fMap, (int) fODP->CD.waiting));
- KMDTrace(kmdDest, 5, "New waiting: 0x%06x\n", fODP->CD.waiting);
- }
- fODP->CD.tag.setUpDone = TRUE;
- ActivateCond(theNewLock, (CondODP) fODP);
- break;
- }
-
- case SSTag: {
- register SSODP myODP;
- register AVariablePtr aVar;
- register SSAddr sAddr;
- SSAddr l;
- SSPtr p;
- int oldAbCon;
- int oldODP, delta;
- CodePtr cPtr;
- CodeAddr *returnAddrAddr;
- CodeAddr ip = 0;
- GODP b;
- GODataPtr g;
- SSAddr sp;
- RegisterSave regs, nextRegs;
- SSAddr *regStoredAt[16];
- TemplatePtr tPtr;
- TemplateEntryPtr entry;
- DynamicLinkPtr theLink;
- int i, tOffset, it, k, argumentCount, resultCount;
- IPMapPtr templateMap;
-
- if(isRecovery) goto BADTAG;
-
- p = (SSPtr) fODP;
- myODP = p->ownSSODP;
-
- KMDTrace(kmdDest, 4, "Translating SSOD @ %s OID: 0x%08x process %s\n",
- PPLoc(myODP->ownLoc), myODP->ownOID, PPPOID(myODP->processOID));
- KMDTrace(kmdDest, 5, " SSPtr 0x%05x\n", p);
- {
- register SSAddr **rs;
- /*
- * regStoredAt indicates the address of where a preempted
- * register has been stored. Further down in the stack
- * we find the usage of the register and only then can
- * we translate the stored value.
- * The nextRegs is used for restoring register values
- * while still using the current values.
- */
- KMDTrace("FixMe", 5, "Assume for RegisterF, regs before saved\n");
-
- for (rs = ®StoredAt[0]; rs != ®StoredAt[16]; rs++) {
- *rs = (SSAddr *) NULL;
- }
-
- /*
- * The following ensure that the preempted registers will be
- * translated.
- */
-
- KMDTrace("Portability", 1, "Using absolute reg numbers!\n");
- regStoredAt[4] = (SSAddr *) &p->regs.r4;
- regStoredAt[5] = (SSAddr *) &p->regs.r5;
- regStoredAt[6] = (SSAddr *) &p->regs.r6;
- regStoredAt[7] = (SSAddr *) &p->regs.r7;
- regStoredAt[8] = (SSAddr *) &p->regs.r8;
- regStoredAt[9] = (SSAddr *) &p->regs.r9;
- }
-
- /*
- * Translate status information related to the SS -- primarily
- * the Requests.
- */
-
- if (IsNULL(p)) {
- ErrMsg("** No actual stack segment ???? **\n");
- (void) abort();
- }
-
- if (NonNULL(p->invokePtr)) {
- p->invokePtr = (GenericPtr) TranslateReq((GenericReqPtr) (p->invokePtr), fMap, p);
- }
-
- if (NonNULL(p->rPtr)) {
- p->rPtr = (GenericPtr) TranslateReq((GenericReqPtr) (p->rPtr), fMap, p);
- }
-
- /*
- * First go through the SS state information and translate it.
- * Then translate requests (done above).
- * Traverse and translate the stack area itself.
- *
- * When Digesting the SS, the new address of the stack
- * pointer was put into the translation map (cf. DigestTable).
- * It may then be used for fixing all other addresses internal to
- * the stack segment.
- */
-
- /*
- * Translate the ready queue link.
- * Note, this is only meaningfull for processes that are moved
- * while in queues -- for the time being only conditions and
- * monitor entry. These queues are transferred with their
- * links as hard addresses and are reestablished merely by
- * translating the hard addresses. Thus the entire queue must
- * be sent. This method is not used for processes waiting in
- * the ready queue since usually not all ready processes move at the
- * same time.
- */
- if (NonNULL(p->readyQLink)) {
- p->readyQLink = (SSPtr) Map_Lookup(fMap, (int) p->readyQLink);
- if (IsNIL(p->readyQLink)) p->readyQLink = NULL;
- }
- KMDTrace(kmdDest, 5, "ReadyQLink\t0x%06x\n", p->readyQLink);
-
- /* Translate registers */
- sp = p->regs.sp;
- p->regs.sp = (SSAddr) Map_Lookup(fMap, (int) sp);
- delta = (Offset) byteOffset(sp, p->regs.sp);
- KMDTrace(kmdDest, 5, "sp 0x%06x - > 0x%06x delta %d\n", sp, p->regs.sp, delta);
- sAddr = sp = p->regs.sp;
- regs = p->regs;
-
- /* Translate return ip on top of stack */
- ip = (CodeAddr) TranslateCodeAddr(fMap, * (CodeAddr *) sp);
- returnAddrAddr = (CodeAddr *) sp;
- *returnAddrAddr = ip;
-
- p->regs.l = (SSAddr) addOffset(p->regs.l, delta);
- p->regs.b = (GODP) Map_Lookup(fMap, (int) p->regs.b);
- p->regs.g = (GODataPtr) Map_Lookup(fMap, (int) p->regs.g);
-
- /*
- * Translate the result registers (if necessary)
- */
- switch (p->resultBrand){
- case DataBrand:
- KMDTrace(kmdDest, 4, "Result regs data: (0x%04x,0x%04x)\n",
- p->regs.arg1, p->regs.arg2);
- break;
-
- case ODPBrand: {
- ODP theOldODP, newODP;
-
- theOldODP = (ODP) p->regs.arg1;
- newODP = (ODP) Map_Lookup(fMap, (int) theOldODP);
- p->regs.arg1 = (int) newODP;
- KMDTrace(kmdDest, 4, "Result reg ODP: (0x%06x -> 0x%06x) is %s\n",
- theOldODP, newODP, PPODP((ODP) p->regs.arg1));
- break;
- }
-
- case VariableBrand: {
- AVariablePtr varPtr;
- DataAddr oldAddr;
- AbConPtr oldAbConPtr;
- varPtr = (AVariablePtr) &p->regs.arg1;
-
- oldAddr = varPtr->myAddr;
- oldAbConPtr = varPtr->myAbConPtr;
- TranslateVar(varPtr, fMap);
-
- KMDTrace(kmdDest, 4, "Result reg Var (0x%01x, 0x%01x) -> (0x%01x, 0x%01x), %s\n",
- oldAddr, oldAbConPtr, varPtr->myAddr, varPtr->myAbConPtr, PPVar(varPtr));
- break;
- }
- default:
- ErrMsg("Bad result reg brand %s\n", PPBrand(p->resultBrand));
- abort();
- }
-
- nextRegs = regs;
-
- if (!SSValidAddr(p, sp)) {
- KMDTrace(kmdDest, 5, "** Empty Stack **");
- break;
- }
- l = p->regs.l;
- theLink = mDynLinkPtrFromL(l);
- b = p->regs.b;
- g = p->regs.g;
-
- while (NonNULL(l) && SSValidAddr(p, l)) {
- cPtr = g->myCodePtr;
- if (!PPValidAddr((SSAddr *) cPtr)) {
- KMDTrace(kmdDest, 5, "Bad code ptr for l = 0x%05x\n", l);
- break;
- }
-
- /* Print the current activation record */
- KMDTrace(kmdDest, 4, "<<< Activation record at %s, line %s >>>\n",
- PPCodePtr(cPtr), PPFindLineNo(cPtr, ip));
- KMDTrace(kmdDest, 5,"b = 0x%05x, g = 0x%05x, sp = 0x%05x, l = 0x%05x\n",
- b, g, sp, l);
- KMDTrace(kmdDest, 5, "ip offset: %d (0x%05x)\n",
- byteOffset(cPtr, ip), byteOffset(cPtr, ip));
- if (IsNULL(cPtr->templateMapOffset)) {
- KMDTrace(kmdDest, 5, "No template IPMap\n");
- break;
- }
- templateMap = (IPMapPtr) addOffset(cPtr, cPtr->templateMapOffset);
- tOffset = IPMapLookup(templateMap, byteOffset(cPtr, ip));
-
- if (IsNULL(tOffset)) {
- KMDTrace(kmdDest, 5, "No template for offset\n", byteOffset(cPtr, ip));
- break;
- }
-
- /*
- * Find the number of arguments and results.
- */
-
- tPtr = (TemplatePtr) addOffset(cPtr, tOffset);
- KMDTrace(kmdDest, 4, "%d entr%s in template\n", tPtr->B.numEntries,
- mPLURALY(tPtr->B.numEntries));
- entry = &tPtr->entry[0];
- argumentCount = resultCount = 0;
- for (k = 0; k < tPtr->B.numEntries; k++, entry++){
- if ((entry->TE.SS.Format == ShortStaticF) &&
- (entry->TE.SS.paramInfo != IsNotParam)) {
- /* There are parameters */
- if (entry->TE.SS.paramInfo == IsArgument) {
- argumentCount += entry->TE.SS.count;
- } else resultCount += entry->TE.SS.count;
- } else break;
- }
- aVar=(AVariablePtr) addOffset((theLink+1),
- (argumentCount + resultCount) * sizeof(AVariable));
-
- /*
- * Translate parameters (bottom AR only)
- */
-
- entry = &tPtr->entry[0];
- if (IsNULL(theLink->l)) /* do params only for bottom AR*/
- for (k = 0; k < tPtr->B.numEntries; k++, entry++)
- if ((entry->TE.SS.Format == ShortStaticF) &&
- (entry->TE.SS.paramInfo != IsNotParam)) {
-
- /* There are parameters AND it is the bottom AR */
- KMDTrace(kmdDest, 5, "\tShortStaticF\t(%s) %s\tcount =%4d\n",
- BrandNames[(int)entry->TE.SS.theBrand],
- entry->TE.SS.paramInfo != IsNotParam ? "isParam" : " ",
- entry->TE.SS.count);
- KMDTrace(kmdDest, 4, "%d parameter%s\n", entry->TE.SS.count,
- mPLURAL(entry->TE.SS.count));
- for (i = entry->TE.SS.count; i > 0 ; i--) {
- aVar--; /* Since we are going backwards */
- TranslateVar(aVar, fMap);
-
- KMDTrace(kmdDest, 5, "%6d: %s #%d: %s\n", byteOffset(l, aVar),
- ((entry->TE.SS.paramInfo == IsArgument) ? "Param" : "Result"),
- i, PPVar(aVar));
- }
- } else break;
-
- /* Translate dynamic link */
- if (IsNULL(theLink->l)) {
- KMDTrace(kmdDest, 4, "%4d: DynamicLink, old l: 0x%05x (bottom)\n",
- byteOffset(l, &theLink->l), theLink->l);
- theLink->b = b;
- theLink->g = g;
- } else {
- theLink->l = (SSAddr) addOffset(theLink->l, delta);
- KMDTrace(kmdDest, 4, "%4d: DynamicLink, old l: 0x%05x (%d)\n",
- byteOffset(l, &theLink->l), theLink->l, byteOffset(l, theLink->l));
- theLink->b = (GODP) Map_Lookup(fMap, (int) theLink->b);
- theLink->g = (GODataPtr) Map_Lookup(fMap, (int) theLink->g);
- }
-
- theLink->ip = TranslateCodeAddr(fMap, theLink->ip);
-
- KMDTrace(kmdDest, 5, "%4d: DynamicLink, old g: 0x%05x\n",
- byteOffset(l, &theLink->g), theLink->g);
- KMDTrace(kmdDest, 5, "%4d: DynamicLink, old b: 0x%05x\n",
- byteOffset(l, &theLink->b), theLink->b);
- KMDTrace(kmdDest, 5, "%4d: DynamicLink, old ip: 0x%05x\n",
- byteOffset(l, &theLink->ip), theLink->ip);
- sAddr = (SSAddr) theLink;
- entry = &tPtr->entry[0];
-
- for (it = 0; it < tPtr->B.numEntries; it++) {
- if (entry->TE.SS.Format == RegisterF) {
- register int reg, h;
- register TemplateEntryPtr t = entry;
-
- KMDTrace(kmdDest, 5, "\tRegisterF\t(%s),\t%s, r%d, count %d\n",
- BrandNames[(int)t->TE.R.theBrand],
- t->TE.R.storedWhere == InRegister ? "InRegister" : "InSaveArea",
- t->TE.R.reg, t->TE.R.count);
- if (t->TE.R.storedWhere == InSaveArea) {
- for (reg = t->TE.R.count ; --reg >= 0;) {
- /* Registers are stored low number, low addr */
- sAddr--; /* Since we are going backwards */
- KMDTrace(kmdDest,5,"%4d: Saved Register r%d (0x%06x):\t0x%08x\n",
- byteOffset(l, sAddr), t->TE.R.reg+reg, sAddr, *sAddr);
- /* Remember where register is stored */
- regStoredAt[t->TE.R.reg+reg] = (SSAddr *) sAddr;
- mSetSavedReg(&nextRegs, t->TE.R.reg+reg, *sAddr);
- }
- } else {
- reg = t->TE.R.reg;
- for (h = 0; h < t->TE.R.count; h++, reg++) {
- switch (t->TE.R.theBrand) {
- case DataBrand: {
- KMDTrace(kmdDest, 5, "\tIn r%d: Data:\t0x%08x\n", reg,
- mGetSavedReg(®s, reg));
- break;
- }
- case ODPBrand: {
- ODP regValue;
- regValue = (ODP) mGetSavedReg(®s, reg);
- if (NonNIL(regValue)) {
- regValue = (ODP) Map_Lookup(fMap, (int) regValue);
- }
- KMDTrace(kmdDest, 5, "\tIn r%d: ODP:\t0x%08x\t%s\n",
- reg, regValue, PPODP(regValue));
- /* Translate the stored value too */
- if (NonNULL(regStoredAt[reg])) {
- KMDTrace(kmdDest, 5, "Stored reg #%d at 0x%06x now 0x%06x\n",
- reg, regStoredAt[reg], regValue);
- *regStoredAt[reg] = (SSAddr) regValue;
- regStoredAt[reg] = (SSAddr *) NULL;
- }
- break;
- }
- case VariableBrand: {
- AVariable v;
- v.myAddr = (DataAddr) mGetSavedReg(®s, reg);
- v.myAbConPtr = (AbConPtr) mGetSavedReg(®s, reg+1);
- KMDTrace(kmdDest, 5, "\tIn r%d-%d:\n", reg, reg+1);
- TranslateVar(&v, fMap);
- if (NonNULL(regStoredAt[reg])) {
- KMDTrace(kmdDest, 5, "Saved reg#%d at 0x%06x now 0x%06x\n",
- reg, regStoredAt[reg], v.myAddr);
- *regStoredAt[reg] = (SSAddr) v.myAddr;
- regStoredAt[reg] = (SSAddr *) NULL;
- KMDTrace(kmdDest, 5, "Saved reg#%d at 0x%06x now 0x%06x\n",
- reg+1, regStoredAt[reg+1], v.myAbConPtr);
- *regStoredAt[reg+1] = (SSAddr) v.myAbConPtr;
- regStoredAt[reg+1] = (SSAddr *) NULL;
- }
- h++; reg++; /* Since vars take 2 registers */
- break;
- }
- default:
- ErrMsg("Brand %s not allowed in TraverseAndTranslate\n",
- PPBrand(t->TE.R.theBrand));
- (void) abort();
- } /* end switch (t->TE.R.theBrand) */
- }
- }
- t = (TemplateEntryPtr) addOffset(t, sizeof(t->TE.R));
- entry = t;
- continue;
- }
- assert(entry->TE.SS.Format == ShortStaticF);
- if (entry->TE.SS.paramInfo != IsNotParam) {
- entry++;
- continue;
- }
-
- KMDTrace(kmdDest, 5, "\tShortStaticF\t(%s)\tcount =%4d\n",
- PPBrand(entry->TE.SS.theBrand), entry->TE.SS.count);
-
- switch (entry->TE.SS.theBrand) {
-
- case DataBrand: {
- register int j;
- int intCount;
- if (entry->TE.SS.count == 1) {
- ErrMsg("Warning: DataBrand count of 1, translating %s\n", PPODP(fODP));
- entry->TE.SS.count = 4;
- }
-
- assert (entry->TE.SS.count % sizeof(int) == 0);
- intCount = entry->TE.SS.count/sizeof(int);
- for (j = intCount; j > 0; j--) {
- sAddr--;
- KMDTrace(kmdDest, 5, "%4d: Data: 0x%08x\n", byteOffset(l, sAddr), *sAddr);
- }
- break;
- }
-
- case ODPBrand: {
- register int j;
- register ODP *theODPPtr;
- theODPPtr = (ODP *) sAddr;
- for (j = 1; j <= entry->TE.SS.count; j++) {
- theODPPtr--;
- *theODPPtr = (ODP) Map_Lookup(fMap, (int) *theODPPtr);
- KMDTrace(kmdDest, 5, "%4d: ODP (0x%05x)\n",
- byteOffset(l, theODPPtr), * ((int *) theODPPtr));
- }
- sAddr = (SSAddr) theODPPtr;
- break;
- }
-
- case AddrBrand:
- sAddr -= entry->TE.SS.count;
- KMDTrace(kmdDest, 5, "%4d: Address (0x%05x) count %d\n",
- *(int *)sAddr, entry->TE.SS.count);
- break;
-
-
- case VectorBrand:
- if (entry->TE.SS.theBrand == VectorBrand)
- KMDTrace(kmdDest, 5, "Vector in AR?? ElementBrand = %s\n",
- BrandNames[(int)entry->TE.SS.elementBrand]);
- break;
-
-
- case VariableBrand: {
- register int j;
- register AVariablePtr varPtr;
-
- for (j = 1; j <= entry->TE.SS.count; j++){
- sAddr = (SSAddr) addOffset(sAddr, -sizeof(AVariable));
- varPtr = (AVariablePtr) sAddr;
- /* Translate */
- oldAbCon = (int) varPtr->myAbConPtr;
- oldODP = (int) varPtr->myAddr;
- TranslateVar(varPtr, fMap);
- KMDTrace(kmdDest, 5,
- "%6d: Var (0x%01x, 0x%01x) -> (0x%01x, 0x%01x), %s\n",
- byteOffset(l, sAddr), oldAbCon, oldODP,
- varPtr->myAddr, varPtr->myAbConPtr, PPVar(varPtr));
- }
- break;
- }
-
- case MonitorBrand:
- ErrMsg(" *** Monitor in Activation record !!??\n");
- (void) abort();
- break;
-
- case InvokeQueueBrand: {
- register InvokeQueuePtr iq;
-
- sAddr = (SSAddr) addOffset(sAddr, -sizeof(InvokeQueue));
- iq = (InvokeQueuePtr) sAddr;
- iq->mySSPtr = p;
- iq->next = (InvokeQueuePtr) NULL;
- iq->prev = (InvokeQueuePtr) NULL;
- KMDTrace(kmdDest, 5, "%4d: InvokeQueue (0x%05x, 0x%05x)(0x%05x)\n",
- byteOffset(l, sAddr), *sAddr, *(sAddr+1), *(sAddr+2));
- break;
- }
-
- default:
- ErrMsg("Bad brand %s in mobility.c\n", PPBrand(entry->TE.SS.theBrand));
- (void) abort();
- } /* switch */
-
- entry = (TemplateEntryPtr)
- addOffset(entry, sizeof(ShortStatic));
- }
-
- /* The rest is assumed to be variables */
- {
- register AVariablePtr varPtr;
- varPtr = (AVariablePtr) sAddr;
- varPtr --;
- while (SSValidAddr(p, (SSAddr) varPtr) && ( (SSAddr) varPtr >= sp)) {
- /* Translate */
- oldAbCon = (int) varPtr->myAbConPtr;
- oldODP = (int) varPtr->myAddr;
- TranslateVar(varPtr, fMap);
- KMDTrace(kmdDest, 5, "%6d: Var (0x%01x, 0x%01x) -> (0x%01x, 0x%01x), %s\n",
- byteOffset(l, sAddr), oldAbCon, oldODP,
- varPtr->myAddr, varPtr->myAbConPtr, PPVar(varPtr));
- varPtr--;
- }
- }
- /* Now move on to the next AR (link already translated)*/
- regs = nextRegs; /* Note, not all regs relevant */
- ip = theLink->ip;
- regs.b = b = theLink->b;
- regs.g = g = theLink->g;
- regs.l = l = theLink->l;
- sp = (SSAddr) (theLink+1);
- theLink = mDynLinkPtrFromL(l);
- }
-
- /* We have reached the bottom of the stack segment */
-
- /* Fix the invoke queues */
- FixInvokeQueue(p);
-
- /* Set flags */
- p->tag.setUpDone = TRUE;
- p->ownSSODP->tag.setUpDone = TRUE;
-
- /* Enter the process into relevant queue, if necessary */
- KMDTrace(kmdDest, 3, "%s moved here, status %s in %s\n",
- PPPOID(p->processOID),PPSSRunStatus((int)p->status.rs),
- PPSSPlace(p));
- KMDTrace("LineNumber", 4, "%s moved process arrived in state %s in %s\n",
- PPPOID(p->processOID), PPSSRunStatus((int)p->status.rs),
- PPSSPlace(p));
-
- switch (p->status.rs) {
- case SSRunnable:
- schedule(p);
- break;
-
- case SSInvokeWait:
- KMDTrace(kmdDest, 3, "%s moved here, waiting on invoke, %s\n",
- PPPOID(p->processOID), PPSSPlace(p));
- break;
-
- case SSMonWait:
- case SSCondWait:
- KMDTrace(kmdDest, 3, "%s\n", PPSSRunStatus((int)p->status.rs));
- break;
-
- default:
- ErrMsg("Cannot handle process state %d -- sorry\n",
- PPSSRunStatus((int)p->status.rs));
- }
-
- /* That is all, folks */
- KMDTrace(kmdDest, 4, "******** Translation of AR done ********\n");
- break;
- }
-
- default:
- BADTAG:
- ErrMsg("Bad tag %s\n", PPODBasicTag(fODP->G.tag.tag));
- (void) abort();
- }
- KMDTrace("FixMe", 2, "Should set tag properly in traverse and translate\n");
-
- fODP->G.tag.setUpDone = TRUE;
- fODP->G.tag.frozen = FALSE;
- }
-
-
- /*
- * DoTranslate
- * Traverse the set and translate each using the translation map
- * FixMe note: the fSet should have been a Set, not a Map.
- * Early versions of the kernel had Maps but no Sets
- */
- void DoTranslate(fSet, fTMap, isRecovery)
- Set fSet;
- Map fTMap;
- int isRecovery;
- {
- Set deferredSet;
- ODP theODP;
-
- if (Set_Count(fSet) == 0) return;
-
- deferredSet = (Set) NULL;
-
- Set_For(fSet, theODP)
- if ((theODP->G.tag.tag == SSTag) || (theODP->G.tag.tag == CondTag)){
- /* Do SSs and Conditions last */
- if (IsNULL(deferredSet)) deferredSet = Set_Create();
- Set_Insert(deferredSet, (int) theODP);
- continue;
- }
- KMDTrace("TT", 5, "Will translate 0x%08.8x one of %s\n", theODP,
- PPODBasicTag(theODP->G.tag.tag));
- TraverseAndTranslate(theODP, fTMap, isRecovery);
- Set_Next;
-
- if (IsNULL(deferredSet)) {
- return;
- }
-
- Set_For(deferredSet, theODP)
- KMDTrace("TT", 5, "Will translate 0x%08.8x one of %s\n", theODP,
- PPODBasicTag(theODP->G.tag.tag));
- TraverseAndTranslate(theODP, fTMap, isRecovery);
- Set_Next;
- Set_Destroy(deferredSet);
- }
-
- HResult MoveCallBack(fReq, fOID)
- GenericReqPtr fReq;
- OID fOID;
- {
- _realMoveCallBack(fReq, fOID, 0);
- }
- /**********************************************************************/
- /* MoveCallBack */
- /**********************************************************************/
- /* Call Back */
- void _realMoveCallBack(fReq, fOID, isRecovery)
- GenericReqPtr fReq;
- OID fOID;
- int isRecovery;
- {
- register IncomingMoveReqPtr req = (IncomingMoveReqPtr) fReq;
- char kmdDest[8];
-
- strcpy(kmdDest,(isRecovery ? "Recover" : "Move"));
- KMDTrace(kmdDest, 4, "MoveCallBack; OID %s status %s\n", PPOID(fOID),
- req->status == IMLoadingCode ? "Loading Code" :
- req->status == IMCodeLoadDone? "Code load done" :
- "BAD STATUS");
-
- switch (req->status) {
-
- case IMLoadingCode: {
- ODP oldODP;
- CodeODP newODP;
-
- /* Requested code has arrived */
- oldODP = (ODP) Map_Lookup(req->neededMap, (int) fOID);
-
- if (IsNIL(oldODP)) {
- ErrMsg("MoveCallBack oldODP is nil -- ignored\n");
- return;
- }
- Map_Delete(req->neededMap, (int) fOID);
-
- newODP = (CodeODP) OTLookup(fOID);
- assert(NonNULL(newODP));
-
- /* (Note, m uses the pointer to the code area.) */
- KMDTrace("TT", 5, "TT Map_Insert: (0x%06x -> 0x%06x) for code %s\n",
- oldODP, newODP->dataPtr, PPCodePtr(newODP->dataPtr));
- Map_Insert(req->m, (int) oldODP, (int) newODP->dataPtr);
-
- if (Map_Count(req->neededMap) == 0) {
- KMDTrace(kmdDest, 4, "All needed code loaded\n");
- req->status = IMCodeLoadDone;
- _realMoveCallBack((GenericReqPtr) req, (OID) NULL, isRecovery);
- }
- break;
- }
-
- case IMCodeLoadDone: {
-
-
- DoTranslate(req->newSet, req->m, isRecovery);
-
- /* All done now, cleanup */
- Map_Destroy(req->m);
- Map_Destroy(req->neededMap);
- Set_Destroy(req->newSet);
-
- if(isRecovery){
- /* Gee, where should the recovery process start up? Lets try here
- * this code rehashed from MakeObject in kOps.c
- */
- CodePtr cType;
- register GODP x;
- SSPtr p;
- extern SSPtr NewProcess();
-
- /* figure out how to fill the parameters */
- x = ((GODP)(req->travellerODP));
- assert(x != (GODP) NULL);
- if( ((x->dataPtr) != (struct GOData *)NULL) &&
- ((cType = (CodePtr)(x->dataPtr->myCodePtr))!= (CodePtr)NULL)) {
- /* Now make a global call of the object's recovery section, if any */
- if (cType->recovery.offset) {
- KMDTrace("Recover",4, "Recovery code for object 0x%04x starts\n", x);
- x->tag.setUpDone = FALSE;
- x->tag.frozen = TRUE;
- x->tag.isResident = TRUE;
- x->dataPtr->tag.setUpDone = FALSE;
- x->dataPtr->tag.frozen = TRUE;
- x->dataPtr->tag.isResident= TRUE;
- p = NewProcess();
- StartProcessAtAddr(p, x, x->dataPtr,
- (CodeAddr)addOffset(cType,cType->recovery.offset));
-
- } else { /* No recovery */
- x->tag.setUpDone = TRUE;
- x->tag.frozen = FALSE;
- x->tag.isResident = TRUE;
- x->dataPtr->tag.setUpDone = TRUE;
- x->dataPtr->tag.frozen = FALSE;
- x->dataPtr->tag.isResident= TRUE;
- UnblockInitially(x);
- }
- }
- }
- FreeRequest((GenericReqPtr) req);
- break;
- }
- default: {
- ErrMsg("Bad move status %d in MoveCallBack\n", req->status);
- (void) abort();
- }
- }
- }
-
-
- /* TriggerCallBacks
- *
- * A service routine for objects which may need to load code before they
- * check in. Clients are currently MoveItemHandler and RecoverItemHandler.
- */
- void TriggerCallBacks(fHandlePtr,itemPtr,isRecovery)
- LMHandle *fHandlePtr;
- MoveItem *itemPtr;
- int isRecovery;
- {
- register IncomingMoveReqPtr req;
- OID theCTOID;
- ODP theOldODP = NULL;
- char kmdDest[12];
- HandlerPtr callBack;
- HResult RecoverCallBack();
- extern int onlyFindingOIDs;
-
- strcpy(kmdDest,(isRecovery ? "Recover" : "Move"));
- #ifdef CHECKPOINT
- callBack = (isRecovery ? (GenericHandlerPtr) RecoverCallBack : (GenericHandlerPtr)MoveCallBack);
- #else
- callBack = (GenericHandlerPtr)MoveCallBack;
- #endif
-
- /* Create move/recover request */
- req = mNewRequest(IncomingMove);
- req->hdr.callBack = (GenericHandlerPtr)callBack;
- req->m = Map_Create();
- req->neededMap = Map_Create();
- req->newSet = Set_Create();
-
- DigestTable(fHandlePtr, req->m, req->neededMap, req->newSet, isRecovery);
-
- if(isRecovery){
- /* here is a vain attempt to stuff an ODP where we can get it
- * later to start up recovery processes.
- * rationale: * travellerODP doesn't seem to be used elsewhere.
- * * the OID's are definitely assigned at Checkpoint time.
- * these assertions have not been adequately thought out.
- */
- req->travellerODP = OTLookup(itemPtr->oldODP->G.ownOID);
- }
-
- req->status = IMLoadingCode;
- if (Map_Count(req->neededMap) > 0) { /* Have to load some code */
- Boolean didit;
- Map gotLoaded; /* Holds the ones loaded now */
- CodeODP newODP;
-
- KMDTrace(kmdDest, 4, "%s needs to load %d code files\n",
- kmdDest, Map_Count(req->neededMap));
-
- gotLoaded = Map_Create();
-
- Map_For(req->neededMap, theCTOID, theOldODP)
- KMDTrace(kmdDest, 5, "%s must load %s\n", kmdDest, PPCOID(theCTOID));
- if (isRecovery && onlyFindingOIDs) {
- fprintf(stdout, "0x%8x\n", theCTOID);
- } else {
- didit = LoadRequest(theCTOID, (GenericReqPtr) req);
- if (didit) Map_Insert(gotLoaded, (int) theCTOID, (int) theOldODP);
- }
- Map_Next
-
- Map_For(gotLoaded, theCTOID, theOldODP)
- /* Delete it since no call back will occur */
- Map_Delete(req->neededMap, (int) theCTOID);
- newODP = (CodeODP) OTLookup(theCTOID);
- assert(NonNULL(newODP));
- Map_Insert(req->m, (int) theOldODP, (int) newODP->dataPtr);
- KMDTrace(kmdDest, 5, "%s loaded, (0x%04x -> 0x%04x)\n",
- PPCOID(theCTOID), theOldODP, newODP->dataPtr);
- Map_Next
-
- Map_Destroy(gotLoaded);
- if (Map_Count(req->neededMap) > 0) return;
- }
-
- req->status = IMCodeLoadDone;
- (*callBack)((GenericReqPtr) req, (OID) NULL);
- /* Do not forget to destroy maps when done */
- }
-
- /*
- * MoveItemHandler
- */
- HResult MoveItemHandler(fHandlePtr, fHdr)
- LMHandlePtr fHandlePtr;
- ItemHdr fHdr;
- {
- int size, length;
- MoveItem item;
-
- KMDTrace("Move", 3, "MoveItemHandler\n");
- size = length = fHdr.size - sizeof(fHdr);
- LMGetData(fHandlePtr, &item.oldODP, &length);
- assert (size == length);
- TriggerCallBacks(fHandlePtr, &item,0);
- }
-
-
- /**********************************************************************/
- /* Move */
- /**********************************************************************/
-
- /* Kernel call */
- void Move(fTargetNode, fTargetNodeAbCon)
- GODP fTargetNode;
- AbConPtr fTargetNodeAbCon;
- /* Move the object on top of the stack to the target node
- * The object is moved. The reference is popped off the stack,
- * and the return address is moved down on the stack.
- * The process continues execution when the move has been initiated.
- */
- {
- CodeAddr returnAddr; /* Return addr */
- GODP theODP; /* ODP for object to move */
- AbConPtr theAbCon; /* abcon for same */
- MoveItem item; /* stuff to send */
- Map m; /* ODP moved */
- Set ar; /* ARs to move */
- NodeNum targetLNN; /* where to move to */
- LMHandle myHandle; /* handle for the msg to send */
- KKStatus kstat;
-
- /* Get object reference from stack */
- POPIT(currentSSP->regs.sp, returnAddr);
- POPIT(currentSSP->regs.sp, theODP);
- POPIT(currentSSP->regs.sp, theAbCon);
- PUSHIT(currentSSP->regs.sp, returnAddr);
- KMDTrace("Move", 3, "Move of object (0x%08x, 0x%08x)\n",
- theODP, theAbCon);
-
- /* Start by dispensing with the trivial cases: */
-
- if (!PPValidAddr((SSAddr *) theODP) ||
- !PPValidAddr((SSAddr *) fTargetNode) ||
- !PPValidAddr((SSAddr *) theODP)
- ) {
- KMDTrace("Move", 3, "Object or destination is NIL\n");
- return;
- }
-
- if (fTargetNode->tag.tag != GODTag) {
- KMDTrace("Move", 2, "Bad argument to move.\n");
- fail(preemptRunning());
- return;
- }
-
- KMDTrace("Move", 4, "Object (tag %s) is one of %s\n",
- PPODBasicTag(theODP->tag.tag), PPCOID(theAbCon->CodeOID));
- targetLNN = mGetLocNodeNum(fTargetNode->ownLoc);
-
- if (IsNULL(targetLNN)) {
- KMDTrace("Move", 2, "Target location %s unknown\n",
- PPLoc(fTargetNode->ownLoc));
- KMDTrace("Failure", 3, "Attempt to move obj to unknown loc %s\n",
- PPLoc(fTargetNode->ownLoc));
- unavail(preemptRunning(), fTargetNode, fTargetNodeAbCon);
- return;
- }
-
- if (fTargetNode->tag.isResident || targetLNN == GetLNN()) {
- KMDTrace("Move", 3, "Move to own node; done\n");
- return;
- }
-
- if (theODP->tag.tag == CondTag) {
- KMDTrace("Move", 3, "Move of condition 0x%06x ignored\n", theODP);
- return;
- }
-
- if (theODP->tag.tag != GODTag) {
- ErrMsg("Cannot move object tagged as %s -- possible compiler error\n",
- PPODBasicTag(theODP->tag.tag));
- abort();
- }
-
- /* Is the object remote ? */
- if (!theODP->tag.isResident) {
- ErrMsg("Implementation restriction; cannot move remote object - ignored\n");
- return;
- }
-
- KMDTrace("Move", 5, " one of %s viewed as %s\n",
- PPCOID(theAbCon->CodeOID), PPCOID(theAbCon->ATOID));
-
- /* OK, go for it */
-
- /*
- * Fix up the invokequeues for the currently running so that it will
- * be moved too.
- */
-
- FixInvokeQueue(currentSSP);
-
- kstat = LMStartMsg(&myHandle, KMSG_EmKernel, EMKM_Item, targetLNN);
-
- if (!mSUCCESS(kstat)) {
- KMDTrace("Move", 2, "%s target node #%d unavailable in %s\n",
- PPPOID(currentSSP->processOID), PPLoc(fTargetNode->ownLoc),
- PPSSPlace(currentSSP));
- KMDTrace("Failure", 3, "%s target node #%d unavailable in %s\n",
- PPPOID(currentSSP->processOID), PPLoc(fTargetNode->ownLoc),
- PPSSPlace(currentSSP));
- unavail(preemptRunning(), theODP, theAbCon);
- return;
- }
-
- /* Create moved map and set of ARs to send */
- m = Map_Create();
- ar = Set_Create();
-
- item.hdr.itemTag = MoveITag;
- item.hdr.size = sizeof(item);
- item.oldODP = (ODP) theODP;
- LMPutData(&myHandle, &item, sizeof(item));
-
- MoveToTTable(&myHandle, (ODP) theODP, m, ar);
-
- MoveARs(&myHandle, m, ar);
-
- /* Clean up */
- Map_Destroy(m);
- Set_Destroy(ar);
-
- /*
- * Count number of moves.
- */
- cMV_MovesDone++;
- cMV_MovesBytesSent += LMCurrentPosition(&myHandle);
- cMV_MovesPacketsSent += LMPacketPosition(&myHandle);
-
- kstat = LMSendMsg(&myHandle);
-
- if (!mSUCCESS(kstat)) {
- KMDTrace("Move", 2, "%s target node #%d unavailable in %s\n",
- PPPOID(currentSSP->processOID), targetLNN, PPSSPlace(currentSSP));
- unavail(preemptRunning(), theODP, theAbCon);
- return;
- }
- }
-
- /**********************************************************************/
- /* FixInvokeQueue */
- /**********************************************************************/
-
- void FixInvokeQueue(fSSPtr)
- /* Ensure that the invoke queues are set up.*/
- register SSPtr fSSPtr;
- {
- /*
- * Go thru the activation records and insert into invoke queues
- * until an activation record with the invoke queue is set correctly.
- */
-
- register SSAddr l;
- register DynamicLinkPtr link;
- register GODP b;
- register GODataPtr g;
- register InvokeQueuePtr iq;
- CodeAddr ip;
-
- l = fSSPtr->regs.l;
- if (IsNULL(l)) {
- KMDTrace("InvokeQueue", 3, "Reached bottom of stack segment\n");
- return;
- }
- b = fSSPtr->regs.b;
- g = fSSPtr->regs.g;
- ip = * (CodeAddr *) (fSSPtr->regs.sp);
- KMDTrace("InvokeQueue", 3, "%s fixing invoke queue at %s",
- PPPOID(fSSPtr->processOID), PPGetPos((unsigned int) g,
- (unsigned int) ip));
-
- link = mDynLinkPtrFromL(l);
- if (mStoppedAtEntry(fSSPtr)) {
- KMDTrace("InvokeQueue", 3, "Stopped at entry to %s\n",
- PPSSPlace(fSSPtr));
- l = link->l;
- b = link->b;
- g = link->g;
- ip = link->ip;
- }
-
- while (NonNULL(l)) {
- iq = mInvokeQueuePtrFromL(l);
- link = mDynLinkPtrFromL(l);
- if (iq->mySSPtr != fSSPtr) break;
- KMDTrace("InvokeQueue", 3, "Fixing 0x%04x\n", l);
- KMDTrace("InvokeQueue", 4, "ip = 0x%04x, b = 0x%04x, g = 0x%04x\n",
- ip, b, g);
- KMDTrace("InvokeQueue", 4, "at %s\n", PPGetPos((unsigned int) g,
- (unsigned int) ip));
-
- if (IsNULL(b)) {
- if (IsNULL(link->l)) {
- /* this is the creation stuff hack, ignore it */
- } else {
- ErrMsg("found null b\n");
- (void) abort();
- }
- } else if (b->tag.replicated) {
- if (IsNULL(link->l)) {
- /* this is the creation stuff hack, ignore it */
- } else {
- ErrMsg("found replicated b, tag: %s\n", PPODTag(b->tag));
- (void) abort();
- }
- } else {
- iq->mySSPtr = (SSPtr) - ((int) iq->mySSPtr);
- InsertDQ((DQueuePtr) &b->ARListHead, (DQueuePtr) iq);
- }
-
- l = link->l;
- b = link->b;
- g = link->g;
- ip = link->ip;
- }
- if (IsNULL(l)) {
- KMDTrace("InvokeQueue", 3, "Reached bottom of stack segment\n");
- } else {
- KMDTrace("InvokeQueue", 3, "Invoke OK in %s",
- PPGetPos((unsigned int) g, (unsigned int) ip));
- }
- }
-
- /**********************************************************************/
- /* MoveARs */
- /**********************************************************************/
-
- void MoveARs(fHandlePtr, fSentMap, fARSet)
- LMHandlePtr fHandlePtr;
- Map fSentMap;
- Set fARSet;
- /* Move the ARs in the ARSet */
- {
- register IncomingIReqPtr req;
- register InvokeReqPtr mReq;
- GenericPtr oldReq;
- SSAddr l, topCutAddr, bottomCutAddr, toAddr;
- SSAddr thisL, lastL, newL, oldL;
- CodeAddr currentIP, topCutIP, bottomCutIP, topPreCutIP,
- bottomPreCutIP, oldIp;
- InvokeQueuePtr iq;
- DynamicLinkPtr link, newLink;
- int paramSize, sizeOfCut;
- int topCutArgCount, topCutResultCount;
- int bottomCutArgCount, bottomCutResultCount;
- int delta;
- RegisterSave regs;
- RegisterSave topCutRegs, bottomCutRegs, topPreCutRegs,
- bottomPreCutRegs;
- SSPtr topSSP, middleSSP, bottomSSP, p;
- SSODP middleSSODP, bottomSSODP;
- Boolean goodAR, sendMiddle;
- Boolean sendInitialSS;
- Set ssSet; /* the set of SSs to move */
- Set newARSet; /* any new AR to move */
-
- /*
- * This procedure moves the ARs in the fARSet by
- * - Finding all the SS involved.
- * - Splitting each involved SS into one or more SSs:
- * each of which consists of contiguous ARs that either
- * do or do not move.
- * Note, that each SS may contain multiple ARs that are to
- * be moved.
- * After the splitting, each SS consists only of contiguous ARs that
- * either should be moved or stay.
- * - Move the SSs that need to move.
- */
-
- /*
- * Search for ARs not in ARList.
- * CurrentSSP, ReadyQ, StoppedQ.
- * add them to the ssSet.
- * This is necessary since processes may wait at the entry to
- * operations BEFORE they set up the InvokeQueue.
- * (Note, processes waiting on IO and in a Timed Wait need not
- * be considered: These operations are invoked on FIXed objects.)
- */
-
- if (NonNULL(currentSSP) && (
- (RefStatus) Map_Lookup(fSentMap, (int)currentSSP->regs.b) == RefMoved)
- ) {
- KMDTrace("Move", 3, "The currently running SS %s must move\n",
- PPPOID(currentSSP->processOID));
- Set_Insert(fARSet, (int) currentSSP->regs.l);
- /* Preempt it */
- (void) preemptRunning();
- }
-
- if (NonNULL(readyQ)) {
- register SSPtr last, q;
- last = p = q = readyQ;
- do {
- p = p->readyQLink;
- if ((RefStatus) Map_Lookup(fSentMap, (int) p->regs.b) == RefMoved) {
- /* Found it, now remove from readyQ and stop it */
- /* Delink the one pointed to by p */
- q->readyQLink = p->readyQLink;
- if (p == q) {
- /* removing the only entry */
- readyQ = (SSPtr) NULL;
- } else if (p == last) {
- /* removing the entry at the end of the queue */
- readyQ = q;
- }
- cEmRunnable--;
-
- Set_Insert(fARSet, (int) p->regs.l);
- KMDTrace("Move", 4,
- "%s: l = 0x%06x to be moved; top AR is %s\n",
- PPPOID(p->processOID), p->regs.l, PPSSPlace(p));
- KMDTrace("ProcessSwitch", 3,
- "%s moving off this node in %s\n", PPPOID(p->processOID),
- PPSSPlace(p));
- } else q = p;
- } while (last != p);
- }
-
- if (NonNULL(stoppedQ)) {
- register SSPtr last, q;
- last = p = q = stoppedQ;
- do {
- p = p->readyQLink;
- if ((RefStatus) Map_Lookup(fSentMap, (int) p->regs.b) == RefMoved) {
-
- /* Found it, now remove from readyQ and stop it */
- /* Delink the one pointed to by p */
- q->readyQLink = p->readyQLink;
- if (p == q) {
- /* removing the only entry */
- stoppedQ = (SSPtr) NULL;
- } else if (p == last) {
- /* removing the entry at the end of the queue */
- stoppedQ = q;
- }
-
- Set_Insert(fARSet, (int) p->regs.l);
- KMDTrace("Move", 4, "%s: act rec 0x%06x to be moved; at %s\n",
- PPPOID(p->processOID), p->regs.l, PPSSPlace(p));
- KMDTrace("ProcessSwitch", 3,
- "%s moving off this node in %s\n", PPPOID(p->processOID),
- PPSSPlace(p));
-
- } else q = p;
- } while (last != p);
- }
-
- KMDTrace("FixMe", 3,
- "Still need to do waiting processes (Locate, Move, Conform)\n");
-
- KMDTrace("Move", 4, "There are %d ARs to be moved:\n", Set_Count(fARSet));
-
- if (Set_Count(fARSet) == 0) return;
-
- /*
- * Generate list of SSs to be analysed for moving by traversing the set
- * of ARs to be moved. At the same time, remove the ARs from their
- * invokeQueues and mark it as removed by complementing the
- * SSPtr field (so that it now is back to being a real pointer).
- */
-
-
- newARSet = Set_Create();
- ssSet = Set_Create();
- Set_For(fARSet, l)
- /* Reset invoke queue */
- EnsureRemovedFromInvokeQueue(l);
- iq = mInvokeQueuePtrFromL(l);
-
- /* Insert into set of SSs to look at */
- Set_Insert(ssSet, (int) iq->mySSPtr);
- KMDTrace("Move", 5, "%s AR l = 0%06x, SS: %s\n",
- PPPOID(iq->mySSPtr->processOID), l, PPSSPlace(iq->mySSPtr));
- Set_Next
-
-
- Set_For(ssSet, p)
- /* Move ARs in the stacksegment p */
-
- KMDTrace("Move", 3, "Moving ARs in %s\n", PPPOID(p->processOID));
-
- /*
- * The algorithm for splitting one stack segment containing
- * multiple ARs that either move or do not move is kind of hairy.
- * This code is fairly long; most of it being concerned with fixing
- * addresses and setting the right registers. At the heart of the
- * algorithm is a loop which crawls down the stack examining one
- * activation record at a time. Each time a contiguous set of ARs
- * that 1. are to move, and 2. are surrounded by non-moving ARs (or
- * an end of the stack) is found, this set is copied into a new SS
- * which is then moved.
- *
- * Since we cannot have a stack with "holes" in the middle then
- * every set of contiguous non-moving ARs are also copied, but not
- * moved. At the point where the stack is cut the two new pieces are
- * changed so that it looks like a remote procedure call, i.e., the
- * top of one SS is set to look like a remote call, while the bottom
- * of the other SS is set to look like an incoming remote call.
- */
-
- sendInitialSS = Set_Member(fARSet, (int) p->regs.l);
- sendMiddle = ! sendInitialSS;
-
- topSSP = p;
-
- /* First time, the IP for the next AR is found on the stack */
- currentIP = (CodeAddr) *p->regs.sp;
- regs = p->regs;
-
- KMDTrace("Move", 4, "Start in AR 0x%06x in %s\n", regs.l,
- PPSSPlace(p));
-
- do {
- KMDTrace("Move", 4, "In top: AR 0x%04x in %s\n", regs.l,
- PPRegsPlace(®s, currentIP));
- if (sendMiddle && !mRegsStoppedAtEntry(®s)) {
- /* cannot remove if stopped at entry since no InvkQueue */
- EnsureRemovedFromInvokeQueue(regs.l);
- }
- topPreCutRegs = regs;
- topPreCutIP = currentIP;
- goodAR = MoveDownStack(®s, ¤tIP);
- } while (goodAR && (sendMiddle != Set_Member(fARSet, (int) regs.l)));
-
- topCutRegs = regs;
- topCutIP = currentIP;
-
- if (!goodAR) {
- if (sendMiddle) {
- KMDTrace("Move", 3, "Entire SS to stay\n");
- }
- KMDTrace("Move", 3, "Entire SS to move\n");
- MoveSSODToTTable(fHandlePtr, p->ownSSODP, fSentMap, newARSet,
- p->endOfSS);
-
- FreeUpMovedStackSegment(p);
-
- continue;
- }
-
- /* There are at least two parts in this SS */
-
- if (sendInitialSS) {
- /*
- * Ups, the top must move, handle this specially.
- * Insert a cut. Send the original SS and make a note
- * that it should be deleted when done with all the ARs
- * in it.
- */
- KMDTrace("Move", 3, "Top of the stack segment must move\n");
-
- /*
- * Set it up so that the topmost part in the following is called
- * the middle.
- */
-
- middleSSP = p;
- middleSSODP = middleSSP->ownSSODP;
-
- bottomPreCutRegs = topPreCutRegs;
- bottomPreCutIP = topPreCutIP;
- bottomCutRegs = topCutRegs;
- bottomCutIP = topCutIP;
-
- oldReq = middleSSP->rPtr;
-
- /*
- * Request for invoke return of middle SS
- */
-
- bottomSSP = NewStackSegment(p->segmentSize);
- bottomSSODP = bottomSSP->ownSSODP;
-
- FindParamSizes(&bottomPreCutRegs, bottomPreCutIP,
- &bottomCutArgCount, &bottomCutResultCount);
-
- req = mNewRequest(IncomingI);
- req->status = IHCodeLoadDone;
- req->theProcess = middleSSP;
- req->i.callerSSOID = bottomSSP->ownOID;
- req->i.callerLoc = bottomSSODP->ownLoc;
- req->i.argumentCount = bottomCutArgCount;
- req->i.resultCount = bottomCutResultCount;
- req->i.processOID = topSSP->processOID;
- req->i.targetOID = bottomPreCutRegs.b->ownOID;
- req->i.targetTryAtLoc = bottomPreCutRegs.b->ownLoc;
- req->visitorSet = (Set) NULL;
-
- middleSSP->rPtr = (GenericPtr) req;
-
- /* Set the return at the bottom of the area to move, so that it
- * will return to the kernel.
- * Note: we thus squish the values and need to restore them
- * after the send since they are needed in the first iteration of
- * the loop.
- */
- link = mDynLinkPtrFromL(bottomPreCutRegs.l);
- oldL = link->l;
- oldIp = link->ip;
- link->l = (SSAddr) NULL;
- link->ip = (CodeAddr) &ReturnOffStack;
-
- paramSize = sizeof(AVariable) *
- (bottomCutArgCount+bottomCutResultCount);
- bottomCutAddr = (SSAddr)
- addOffset(bottomCutRegs.sp, paramSize);
- sizeOfCut = (int)
- byteOffset(middleSSP->regs.sp, bottomCutAddr);
-
- KMDTrace("Move", 5, "OK, cut the initialSS at 0x%06x\n",
- bottomCutAddr);
- KMDTrace("Move", 5, "Cut %d bytes, paramSize %d\n", sizeOfCut,
- paramSize);
- KMDTrace("Move", 5, "bottomPreCut link @ 0x%06x, cut.sp 0x%06x\n",
- link, bottomCutRegs.sp);
-
- /* Send the middleSSP */
- MoveSSODToTTable(fHandlePtr, middleSSP->ownSSODP, fSentMap,
- newARSet, bottomCutAddr);
-
- /* restore squished dynamic link */
- link->l = oldL;
- link->ip = oldIp;
-
- /* Note, that this stack segment is freed later */
-
- /* We just sent the middle so do not send the next one */
- sendMiddle = ! sendMiddle;
-
- goto AFTERSEND;
- }
-
- /*
- * Request for invoke return of top SS
- */
-
- middleSSP = NewStackSegment(p->segmentSize);
- middleSSODP = middleSSP->ownSSODP;
-
- FindParamSizes(&topPreCutRegs, topPreCutIP, &topCutArgCount,
- &topCutResultCount);
-
- req = mNewRequest(IncomingI);
- req->status = IHCodeLoadDone;
- req->theProcess = topSSP;
- req->i.callerSSOID = middleSSP->ownOID;
- req->i.callerLoc = middleSSODP->ownLoc;
- req->i.argumentCount = topCutArgCount;
- req->i.resultCount = topCutResultCount;
- req->i.processOID = topSSP->processOID;
- req->i.targetOID = topPreCutRegs.b->ownOID;
- req->i.targetTryAtLoc = topPreCutRegs.b->ownLoc;
- req->visitorSet = (Set) NULL;
-
- oldReq = topSSP->rPtr;
- topSSP->rPtr = (GenericPtr) req;
-
- PREPARENEXTSS:
-
- /* In the following, the variable sendMiddle indicates whether or
- * we are going to send the SS being built. */
- /* Skip down SS until we find an AR that is to be moved */
-
- currentIP = topCutIP;
- regs = topCutRegs;
-
- do {
- KMDTrace("Move", 4, "In middle: AR 0x%04x in %s\n", regs.l,
- PPRegsPlace(®s, currentIP));
- if (!mRegsStoppedAtEntry(®s)) {
- EnsureRemovedFromInvokeQueue(regs.l);
- }
- bottomPreCutRegs= regs;
- bottomPreCutIP = currentIP;
- goodAR = MoveDownStack(®s, ¤tIP);
- } while (goodAR && (sendMiddle == Set_Member(fARSet, (int) regs.l)));
-
- /* Save second cut point */
- bottomCutRegs = regs;
- bottomCutIP = currentIP;
-
- /*
- * Note, in the following, the Boolean flag sendMiddle indicates
- * whether the middle part (as described below) is to be sent
- * or if it is to stay (and the top and bottom are to be sent).
- * On each iteration, the flag is flipped since the old middle
- * becomes the new top.
- * To get into this loop you will note a separate handling of the
- * situations:
- * - the entire stack segment must move (easy).
- * - the entire stack segment must stay (should not occur).
- * - the first AR or (ARs) are to move AND underneath these are
- * ARs that are to remain (in this case the loop is
- * entered via a goto, search for "goto" above).
- *
- * At this point, the first group of ARs to be moved have been
- * located. Three stack parts have been identified:
- * top The non-moving ARs on the top of the SS
- * middle The first group of ARs to move
- * bottom The rest.
- *
- * the following variables identify the parts.
- *
- * Variable: Describes registers for:
- * topPreCutRegs last non-moving AR, from top.
- * topCutRegs first AR to move, from top.
- * bottomPreCutRegs last AR in first group to move.
- * bottomCutRegs first non-moving AR after group.
- *
- * Now we can start cutting.
- * We cut the stack segment in three. The top remains but
- * will have a large hole in the bottom of the segment.
- * The middle is allocated as a new stack segment.
- * The bottom will be processes in this loop as the middle part
- * of the next iteration.
- */
-
- /* Buildup new stack segments and their requests */
-
- middleSSP->availStack = p->availStack -
- byteOffset(bottomCutRegs.sp, p->endOfSS); /* the bottom */
- middleSSP->processOID = p->processOID;
-
- /* Calculate extent of area to copy
- * the area extends from topCutRegs.sp to the
- * end of the parameter area for the AR indicated by
- * bottomPreCutRegs.
- */
- topCutAddr = (SSAddr) topCutRegs.sp;
- FindParamSizes(&bottomPreCutRegs, bottomPreCutIP,
- &bottomCutArgCount, &bottomCutResultCount);
- paramSize = sizeof(AVariable) *
- (bottomCutArgCount+bottomCutResultCount);
- bottomCutAddr = (SSAddr)
- addOffset(bottomCutRegs.sp, paramSize);
- sizeOfCut = (int)
- byteOffset(topCutAddr, bottomCutAddr);
- toAddr = (SSAddr)
- addOffset(middleSSP->endOfSS, -sizeOfCut);
-
- /* Copy into new Stack Segment and retranslate */
- bcopy((char *) topCutAddr, (char *) toAddr, sizeOfCut);
-
- /* set up regs */
- /* delta is the distance relocated */
- delta = (int) byteOffset(topCutAddr, toAddr);
- middleSSP->regs = topCutRegs;
- middleSSP->regs.l = (SSAddr) addOffset(topCutRegs.l, delta);
- middleSSP->regs.sp = (SSAddr) addOffset(topCutRegs.sp, delta);
-
- /* Set return address onto stack */
- PUSHIT(middleSSP->regs.sp,topCutIP);
-
- /* traverse and relocate l in the copied ARs */
- thisL = topCutRegs.l;
- link = mDynLinkPtrFromL(thisL);
- newLink = (DynamicLinkPtr) addOffset(link, delta);
- lastL = bottomPreCutRegs.l;
- while (NonNULL(link->l) && (thisL != lastL)) {
- newL = (SSAddr) addOffset(link->l, delta);
- newLink->l = newL;
- newLink = mDynLinkPtrFromL(newL);
- thisL = link->l;
- link = mDynLinkPtrFromL(thisL);
- }
- /* Set l to NULL at bottom of new SS */
- newLink->l = (SSAddr) NULL;
- newLink->ip = (CodeAddr) &ReturnOffStack;
-
- /* Set l to NULL at bottom of old SS */
- link = mDynLinkPtrFromL(topPreCutRegs.l);
- link->l = (SSAddr) NULL;
- link->ip = (CodeAddr) &ReturnOffStack;
-
- /* end of cutting */
- /*************************************************************/
-
- /* Set up return requests */
- /* Notes:
- In the invoke reply message only the following need be set:
- theProcess
- i.argumentCount
- i.resultCount
- status
- i.callerSSOID
- i.callerLoc
- i.processOID
- i.targetOID
- i.targetTryAtLoc (?)
- */
-
-
- /* Build a request for the middle segment */
- mReq = mNewRequest(Invoke);
- mReq->status = IRWaitingForInvokeReply;
- mReq->requestor = (SSPtr) middleSSP;
- mReq->targetGODP = topPreCutRegs.b;
- mReq->i = req->i;
- middleSSP->invokePtr = (GenericPtr) mReq;
- middleSSP->status.rs = SSInvokeWait;
-
- if (NonNULL(bottomCutRegs.l)) {
- /*
- * Request for invoke return of middle SS
- */
-
- bottomSSP = NewStackSegment(p->segmentSize);
- bottomSSODP = bottomSSP->ownSSODP;
-
- FindParamSizes(&bottomPreCutRegs, bottomPreCutIP,
- &bottomCutArgCount, &bottomCutResultCount);
-
- req = mNewRequest(IncomingI);
- req->status = IHCodeLoadDone;
- req->theProcess = middleSSP;
- req->i.callerSSOID = bottomSSP->ownOID;
- req->i.callerLoc = bottomSSODP->ownLoc;
- req->i.argumentCount = bottomCutArgCount;
- req->i.resultCount = bottomCutResultCount;
- req->i.processOID = topSSP->processOID;
- req->i.targetOID = bottomPreCutRegs.b->ownOID;
- req->i.targetTryAtLoc = bottomPreCutRegs.b->ownLoc;
- req->visitorSet = (Set) NULL;
-
- middleSSP->rPtr = (GenericPtr) req;
- } else {
- middleSSP->rPtr = oldReq;
- }
-
- if (sendMiddle) {
- /* Send the middleSSP */
- MoveSSODToTTable(fHandlePtr, middleSSP->ownSSODP, fSentMap,
- newARSet, middleSSP->endOfSS);
- /* Cleanup */
- FreeUpMovedStackSegment(middleSSP);
- }
-
- AFTERSEND:
-
- /* Check to see if there are more ARs in the stack segment */
- if (NonNULL(bottomCutRegs.l)) {
- /* Prepare for next set of ARs */
- topCutRegs = bottomCutRegs;
- topCutIP = bottomCutIP;
-
- topSSP = middleSSP;
-
- middleSSP = bottomSSP;
- middleSSODP = bottomSSODP;
-
- sendMiddle = !sendMiddle;
- goto PREPARENEXTSS; /* OK, OK, so I goofed -- should be loop */
- }
-
- if (sendInitialSS) {
- KMDTrace("Move", 4, "Freeing initial SS %s\n", PPOID(p->ownOID));
- /* Cleanup */
- FreeUpMovedStackSegment(p);
- }
-
- Set_Next
-
- Set_Destroy(ssSet);
-
- /*
- * Now recursively process the ARs that transitively are to move.
- */
- KMDTrace("Move", 4, "Recursively moving %d ARs\n", Set_Count(newARSet));
- MoveARs(fHandlePtr, fSentMap, newARSet);
-
- Set_Destroy(newARSet);
- }
-
- /**********************************************************************/
- /* MoveSSODToTTable */
- /**********************************************************************/
-
- void MoveSSODToTTable(fHandlePtr, fSSODP, fSentMap, fARSet, fHighAddress)
- LMHandle *fHandlePtr;
- register SSODP fSSODP;
- Map fSentMap;
- Set fARSet;
- SSAddr fHighAddress;
- /*
- * Add the necessary information to the LMMsg given for sending the SS
- * given by fODP across the network. Enter the ODP in the SentMap.
- * Enter any ARs that are to move in the fARSet.
- * Do only once for each SSODP -- ignore duplicate requests
- */
- {
- CodePtr cPtr;
- register SSPtr p;
- register SSAddr sAddr;
- register SSAddr l;
- RegisterSave regs;
- CodeAddr ip = 0;
- GODP b;
- GODataPtr g;
- SSAddr sp;
- TemplatePtr tPtr;
- register TemplateEntryPtr entry;
- AVariablePtr aVar;
- DynamicLinkPtr theLink;
- int i, tOffset, it, k, argumentCount, resultCount;
- int sizeOfCut;
- IPMapPtr templateMap;
- TTMoveSSODEntry ssodentry;
- RefStatus status;
-
-
- status = (RefStatus) Map_Lookup(fSentMap, (int) fSSODP);
-
- if (((int) status != EMNIL) && (status == RefMoved) ) {
- KMDTrace("TT", 5, "MoveTT: SS: 0x%05x already moved!!\n", fSSODP);
- return;
- }
-
- Map_Insert(fSentMap, (int) fSSODP, (int)RefMoved);
- fSSODP->tag.seenHere = TRUE;
-
- if (IsNULL(fSSODP->ownOID)) {
- fSSODP->ownOID = fSSODP->dataPtr->ownOID = getNextOID();
- OTInsert((ODP) fSSODP);
- }
- p = (SSPtr) fSSODP->dataPtr;
-
- if (IsNULL(p)) {
- ErrMsg("** NIL stack segment **\n");
- (void) abort();
- }
-
- KMDTrace("Move", 3, "Moving STACK SEGMENT %s, Process %s in %s\n",
- PPOID(p->ownOID), PPPOID(p->processOID), PPSSPlace(p));
- KMDTrace("Move", 5, "SSPtr 0x%05x\n", p);
- KMDTrace("Move", 3, "Status:\t\t\t%s%s\n", PPSSRunStatus((int)p->status.rs),
- (mStoppedAtEntry(p) && p->status.rs != SSNotInUse) ?
- " Stopped at Operation Entry" : "");
- KMDTrace("Move", 5, "Segment Size: \t\t%4d\n", p->segmentSize);
- KMDTrace("Move", 5, "Available: \t\t%4d\n", p->availStack);
- KMDTrace("Move", 5, "splimit: \t\t0x%06x (low address)\n", p->splimit);
- KMDTrace("Move", 5, "sp \t\t0x%06x (stack top)\n", p->regs.sp);
- KMDTrace("Move", 5, "bottom: \t\t0x%06x (highest address)\n",
- fHighAddress);
- KMDTrace("Move", 5, "SS end: \t\t0x%06x\n", p->endOfSS);
-
- sAddr = sp = p->regs.sp;
- if (!SSValidAddr(p, sp)) {
- ErrMsg("** Empty Stack **\n");
- (void) abort();
- }
-
- ip = * (CodeAddr *) sp;
- l = p->regs.l;
- theLink = mDynLinkPtrFromL(l);
- b = p->regs.b;
- g = p->regs.g;
- regs = p->regs;
-
- while (NonNULL(l) && SSValidAddr(p, l)) {
- cPtr = g->myCodePtr;
- if (IsNULL(cPtr)) {
- KMDTrace("Move", 5, "Bad code ptr for l = 0x%05x\n", l);
- break;
- }
-
- /* Print the current activation record */
- KMDTrace("Move", 4, "\nActivation record at %s, line %s\n",
- PPCodePtr(cPtr), PPFindLineNo(cPtr, ip));
- KMDTrace("Move", 5,
- "b = 0x%05x, g = 0x%05x, sp = 0x%05x, l = 0x%05x\n", b, g, sp, l);
- KMDTrace("Move", 5, "ip offset: %d (0x%05x)\n", byteOffset(cPtr, ip),
- byteOffset(cPtr, ip));
-
- AddCodeAddrToTTable(fHandlePtr, cPtr, ip, fSentMap, fARSet);
-
- if (IsNULL(cPtr->templateMapOffset)) {
- KMDTrace("Move", 5, "No template IPMap\n");
- break;
- }
- templateMap = (IPMapPtr) addOffset(cPtr, cPtr->templateMapOffset);
- tOffset = IPMapLookup(templateMap, byteOffset(cPtr, ip));
- if (IsNULL(tOffset)) {
- KMDTrace("Move", 5, "No template for offset\n",
- byteOffset(cPtr, ip));
- break;
- }
- tPtr = (TemplatePtr) addOffset(cPtr, tOffset);
- KMDTrace("Move", 5, "%d entr%s in template\n", tPtr->B.numEntries,
- mPLURALY(tPtr->B.numEntries));
-
- /* Traverse the template and find argument and result counts */
- entry = &tPtr->entry[0];
- argumentCount = resultCount = 0;
- for (k = 0; k < tPtr->B.numEntries; k++, entry++) {
- if ((entry->TE.SS.Format == ShortStaticF) &&
- (entry->TE.SS.paramInfo != IsNotParam)) {
- /* There are parameters */
- if (entry->TE.SS.paramInfo == IsArgument) {
- argumentCount += entry->TE.SS.count;
- } else resultCount += entry->TE.SS.count;
- } else {
- break;
- }
- }
-
- entry = &tPtr->entry[0];
- aVar = (AVariablePtr) addOffset((theLink+1),
- (argumentCount + resultCount) * sizeof(AVariable));
- /* aVar now points to the high addr of the parameters */
-
- if (IsNULL(theLink->l))
- for (k = 0; k < tPtr->B.numEntries; k++, entry++)
- if ((entry->TE.SS.Format == ShortStaticF) &&
- (entry->TE.SS.paramInfo != IsNotParam)) {
- /* There are parameters AND this is the bottom AR */
- KMDTrace("Move", 5,
- "\tShortStaticF\t(%s) %s\tcount =%4d\n",
- BrandNames[(int)entry->TE.SS.theBrand],
- entry->TE.SS.paramInfo != IsNotParam ? "isParam" : " ",
- entry->TE.SS.count);
- KMDTrace("Move", 5, "%d parameter%s\n", entry->TE.SS.count,
- mPLURAL(entry->TE.SS.count));
- for (i = entry->TE.SS.count; i > 0 ; i--) {
- aVar--;
- KMDTrace("Move", 5, "%4d: %s #d (0x%05x, 0x%05x), %s\n",
- byteOffset(l, aVar),
- (entry->TE.SS.paramInfo == IsArgument) ? "Param"
- : "Result", aVar->myAbConPtr, aVar->myAddr, PPVar(aVar));
- AddVarToTTable(fHandlePtr, aVar, fSentMap, fARSet);
- }
- } else {
- break;
- }
-
- /* Print the Dynamic Link */
- if (IsNULL(theLink->l)) {
- KMDTrace("Move", 5,
- "%4d: DynamicLink, old l: 0x%05x (bottom)\n",
- byteOffset(l, &theLink->l), theLink->l);
- } else {
- KMDTrace("Move", 5, "%4d: DynamicLink, old l: 0x%05x (l+%d)\n",
- byteOffset(l, &theLink->l), theLink->l,
- byteOffset(l, theLink->l));
- }
- KMDTrace("Move", 5, "%4d: DynamicLink, old g: 0x%05x\n",
- byteOffset(l, &theLink->g), theLink->g);
- KMDTrace("Move", 5, "%4d: DynamicLink, old b: 0x%05x\n",
- byteOffset(l, &theLink->b), theLink->b);
- KMDTrace("Move", 5, "%4d: DynamicLink, old ip: 0x%05x\n",
- byteOffset(l, &theLink->ip), theLink->ip);
- sAddr = (SSAddr) theLink;
- entry = &tPtr->entry[0];
-
- /* Now traverse the AR data area */
- for (it = 0; it < tPtr->B.numEntries; it++) {
- if (entry->TE.SS.Format == RegisterF) {
- int reg;
- register TemplateEntryPtr t = entry;
-
- KMDTrace("Move", 5,
- "\tRegisterF\t(%s),\t%s, r%d, count %d\n",
- BrandNames[(int)t->TE.R.theBrand],
- t->TE.R.storedWhere == InRegister ? "InRegister"
- : "InSaveArea",
- t->TE.R.reg, t->TE.R.count);
- if (t->TE.R.storedWhere == InSaveArea) {
- for (reg = t->TE.R.count - 1 ; reg >= 0; reg--) {
- /* Registers are stored low number, low addr */
- sAddr--; /* Since we are going backwards */
- KMDTrace("Move", 5,
- "%4d: Saved Register r%d:\t0x%08x\t (@ 0x%06x)\n",
- byteOffset(l, sAddr), t->TE.R.reg+reg, *sAddr,
- sAddr);
- }
- } else {
- for (reg = 0; reg < t->TE.R.count; reg++) {
- switch (t->TE.R.theBrand) {
- case DataBrand: {
- KMDTrace("Move", 5, "\tIn r%d: Data:\t0x%08x\n",
- t->TE.R.reg+reg,
- mGetSavedReg(®s, t->TE.R.reg+reg));
- break;
- }
- case ODPBrand: {
- ODP regValue;
- regValue = (ODP)
- mGetSavedReg(®s, t->TE.R.reg+reg);
- KMDTrace("Move", 5,
- "\tIn r%d: ODP:\t0x%08x\t%s\n",
- t->TE.R.reg+reg, regValue, PPODP(regValue));
- if (entry->TE.R.attachedFlag) {
- MoveToTTable(fHandlePtr, regValue, fSentMap,
- fARSet);
- } else {
- AddToTTable(fHandlePtr, regValue, fSentMap,
- fARSet);
- }
- break;
- }
- case VariableBrand: {
- AVariable v;
- v.myAddr = (DataAddr)
- mGetSavedReg(®s, t->TE.R.reg+reg);
- v.myAbConPtr = (AbConPtr)
- mGetSavedReg(®s, t->TE.R.reg+reg+1);
- KMDTrace("Move", 5, "\tIn r%d-%d: Var: %s\n",
- t->TE.R.reg+reg, t->TE.R.reg+reg, PPVar(&v)
- );
-
- if (entry->TE.R.attachedFlag) {
- MoveVarToTTable(fHandlePtr, &v, fSentMap,
- fARSet);
- } else {
- AddVarToTTable(fHandlePtr, &v, fSentMap,
- fARSet);
- }
- reg++; /* Since vars take 2 registers */
- break;
- }
- default: {
- ErrMsg(
- "Brand %d not allowed in MoveSSODToTTable\n",
- t->TE.R.theBrand);
- (void) abort();
- }
-
- } /* end switch (t->TE.R.theBrand) */
- }
- }
- t = (TemplateEntryPtr) addOffset(t, sizeof(t->TE.R));
- entry = t;
-
- continue;
- }
-
- assert(entry->TE.SS.Format == ShortStaticF);
- if (entry->TE.SS.paramInfo != IsNotParam) {
- entry++;
- continue;
- }
-
- KMDTrace("Move", 5,
- "\tShortStaticF\t(%s)\tcount =%4d\n",
- BrandNames[(int)entry->TE.SS.theBrand],
- entry->TE.SS.count);
-
- switch (entry->TE.SS.theBrand) {
- case DataBrand: {
- register int j;
- int intCount;
- assert (entry->TE.SS.count % sizeof(int) == 0);
- intCount = entry->TE.SS.count/sizeof(int);
- for (j = intCount; j > 0; j--) {
- sAddr--;
- KMDTrace("Move", 5, "%4d: Data: \t0x%08x\n",
- byteOffset(l, sAddr), *sAddr);
- }
- break;
- }
-
- case ODPBrand: {
- register int j;
- register ODP *theODPPtr;
- theODPPtr = (ODP *) sAddr;
- for (j = 1; j <= entry->TE.SS.count; j++) {
- theODPPtr--;
- KMDTrace("Move", 5, "%4d: ODP \t(0x%05x)\n",
- byteOffset(l, theODPPtr), * ((int *) theODPPtr));
- if (entry->TE.SS.attachedFlag) {
- MoveToTTable(fHandlePtr, (ODP) *theODPPtr, fSentMap,
- fARSet);
- } else {
- AddToTTable(fHandlePtr, (ODP) *theODPPtr, fSentMap,
- fARSet);
- }
- }
-
- sAddr = (SSAddr) theODPPtr;
- break;
- }
-
- case AddrBrand:{
- sAddr -= entry->TE.SS.count;
- KMDTrace("Move", 5, "%4d: Address \t(0x%05x) count %d\n",
- *(int *)sAddr, entry->TE.SS.count);
- (void) abort();
- }
-
- case VectorBrand: {
- KMDTrace("Move", 5, "Vector (in SS ??) ElementBrand = %s\n",
- BrandNames[(int)entry->TE.SS.elementBrand]);
- assert(entry->TE.SS.theBrand != VectorBrand);
- (void) abort();
- break;
- }
-
- case VariableBrand: {
- register int j;
- register AVariablePtr varPtr;
-
- for (j = 1; j <= entry->TE.SS.count; j++){
- sAddr = (SSAddr) addOffset(sAddr, -sizeof(AVariable));
- varPtr = (AVariablePtr) sAddr;
- KMDTrace("Move", 5,
- "%4d: Variable\t(0x%04x, 0x%04x) %s\n",
- byteOffset(l, sAddr), varPtr->myAddr,
- varPtr->myAbConPtr, PPVar(varPtr));
- if (entry->TE.SS.attachedFlag) {
- MoveVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
- } else {
- AddVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
- }
- }
- break;
- }
-
- case MonitorBrand: {
- sAddr = (SSAddr) addOffset(sAddr, sizeof(MonitorLock));
- ErrMsg(" *** Monitor in Activation record !!??\n");
- (void) abort();
- break;
- }
-
- case InvokeQueueBrand: {
- sAddr = (SSAddr) addOffset(sAddr, -sizeof(InvokeQueue));
- if (*(sAddr+2) < 0) {
- KMDTrace("Move", 5,
- "%4d: InvokeQueue\t(0x%05x, 0x%05x) *(0x%05x)\n",
- byteOffset(l, sAddr), *sAddr, *(sAddr+1),
- - (*(sAddr+2)));
- } else {
- KMDTrace("Move", 5,
- "%4d: InvokeQueue\t(0x%05x, 0x%05x) (0x%05x)\n",
- byteOffset(l, sAddr), *sAddr, *(sAddr+1),
- (*(sAddr+2)));
- }
- break;
- }
-
- default: {
- KMDTrace("Move", 5, "Bad brand %s in MoveSSODToTTable\n",
- PPBrand(entry->TE.SS.theBrand));
- (void) abort();
- }
-
- } /* end switch (entry->TE.SS.theBrand) */
-
- entry = (TemplateEntryPtr)
- addOffset(entry, sizeof(ShortStatic));
- }
-
- /* The rest is assumed to be variables */
- {
- register AVariablePtr varPtr;
- varPtr = (AVariablePtr) sAddr;
- varPtr --;
- while (SSValidAddr(p, (SSAddr) varPtr) &&
- ( (SSAddr) varPtr >= sp)) {
- KMDTrace("Move", 5, "%4d: Variable (0x%04x, 0x%04x), %s\n",
- byteOffset(l, varPtr),
- varPtr->myAddr, varPtr->myAbConPtr, PPVar(varPtr));
- AddVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
- varPtr--;
- }
- }
- KMDTrace("Move", 5,
- "\n********** End of activation record *********\n");
-
- /* Now move on to the next activation record */
-
- /* Restore registers from register save area */
-
- entry = &tPtr->entry[0];
- sAddr = (SSAddr) theLink;
- for (i = 0; i < tPtr->B.numEntries; i++) {
-
- switch (entry->TE.SS.Format) {
-
- case ShortStaticF: {
- KMDTrace("Move", 5,
- "\tShortStaticF\t(%s) %s\tcount =%4d\tsAddr 0x%06x\n",
- BrandNames[(int)entry->TE.SS.theBrand],
- entry->TE.SS.paramInfo != 0 ? "isParam" : " ",
- entry->TE.SS.count, sAddr);
-
- if (entry->TE.SS.paramInfo != IsNotParam) {
- entry++;
- continue;
- }
-
- switch (entry->TE.SS.theBrand) {
-
- case DataBrand: {
- sAddr = (SSAddr)
- addOffset(sAddr, -entry->TE.SS.count);
- break;
- }
-
- case ODPBrand: {
- sAddr = (SSAddr)
- addOffset(sAddr, -sizeof(ODP)*entry->TE.SS.count);
- break;
- }
-
- case AddrBrand:{
- assert(entry->TE.SS.theBrand != AddrBrand);
- (void) abort();
- break;
- }
-
- case VectorBrand: {
- break;
- } /* case Vector Brand */
-
- case VariableBrand: {
- sAddr = (SSAddr)
- addOffset(sAddr, -sizeof(AVariable)*entry->TE.SS.count);
- break;
- }
-
- case MonitorBrand: {
- sAddr = (SSAddr)
- addOffset(sAddr, -sizeof(MonitorLock));
- ErrMsg("MonitorBrand in AR\n");
- assert(entry->TE.SS.theBrand != MonitorBrand);
- (void) abort();
- }
-
- case InvokeQueueBrand: {
- sAddr = (SSAddr) addOffset(sAddr, -sizeof(InvokeQueue));
- break;
- }
-
- default: {
- ErrMsg("Bad brand %s in MoveSSODToTTable (ARend)\n",
- PPBrand(entry->TE.SS.theBrand));
- (void) abort();
- break;
- }
-
- } /* end switch (entry->TE.SS.theBrand) */
-
- entry = (TemplateEntryPtr)
- addOffset(entry, sizeof(ShortStatic));
- break;
- }
-
- case RegisterF: {
- KMDTrace("Move", 5,
- "\tRegisterF\t(%s),\t%s, r%d, count %d, sAddr 0x%06x\n",
- BrandNames[(int)entry->TE.R.theBrand],
- entry->TE.R.storedWhere == InRegister ? "InRegister"
- : "InSaveArea", entry->TE.R.reg, entry->TE.R.count,
- sAddr);
- if (entry->TE.R.storedWhere == InSaveArea) {
- for (k = entry->TE.R.count - 1 ; k >= 0; k--) {
- /* Registers are stored low number, low addr */
- sAddr--; /* Since we are going backwards, do -- first */
- KMDTrace("Move", 5,
- "Restoring r%d, was 0x%02x, now 0x%02x from 0x%06x\n",
- entry->TE.R.reg+k,
- mGetSavedReg(®s, entry->TE.R.reg+k),
- *sAddr, sAddr);
- mSetSavedReg(®s, entry->TE.R.reg+k, *sAddr);
- }
- }
- entry = (TemplateEntryPtr)
- addOffset(entry, sizeof(entry->TE.R));
- break;
- } /* case RegisterF */
-
- default: {
- ErrMsg("Bad format 0x%02x in MoveSSODToTTable\n",
- entry->TE.SS.Format);
- (void) abort();
- break;
- } /* default action */
-
- } /* switch on entry->TE.SS.Format */
- } /* for (i = 0; ...) */
-
-
- ip = theLink->ip;
- b = theLink->b;
- g = theLink->g;
- l = theLink->l;
- sp = (SSAddr) (theLink+1);
- theLink = mDynLinkPtrFromL(l);
- } /* while there are more ARs */
-
- /* Send the CodeAddr for the return (a kernel addr) */
- AddCodeAddrToTTable(fHandlePtr, (CodePtr) NULL, ip, fSentMap, fARSet);
-
- /* Now send the Requests */
- if (NonNULL(p->rPtr)) {
- AddReqToTTable(fHandlePtr, p->rPtr, fSentMap, fARSet);
- }
-
- if (NonNULL(p->invokePtr)) {
- AddReqToTTable(fHandlePtr, p->invokePtr, fSentMap, fARSet);
- }
-
- /* Send the result registers (if not DataBrand) */
- switch (p->resultBrand){
- case DataBrand: {
- KMDTrace("Move", 4, "Result regs data: (0x%04x,0x%04x)\n", p->regs.arg1,
- p->regs.arg2);
- break;
- }
- case ODPBrand: {
- KMDTrace("Move", 4, "Result reg ODP: %s\n",
- PPODP((ODP) p->regs.arg1));
- AddToTTable(fHandlePtr, (ODP) p->regs.arg1, fSentMap, fARSet);
- break;
- }
- case VariableBrand: {
- KMDTrace("Move", 4, "Result reg Var: %s\n",
- PPVar((AVariablePtr) &p->regs.arg1));
- AddVarToTTable(fHandlePtr, (AVariablePtr) p->regs.arg1, fSentMap,
- fARSet);
- break;
- }
- default: {
- ErrMsg("Bad result reg brand %s\n", PPBrand(p->resultBrand));
- abort();
- }
- }
-
- /* Send the SS */
- sizeOfCut = byteOffset(p->regs.sp, fHighAddress);
- ssodentry.hdr.itemTag = TTMoveSSODITag;
- ssodentry.hdr.size = sizeof(TTMoveSSODEntry) + sizeOfCut;
- KMDTrace("Move", 4, "Size of SSOD: %d + %d = %d\n",
- sizeof(TTMoveSSODEntry), sizeOfCut, ssodentry.hdr.size);
- UpdateLocation(fSSODP->ownOID, NewLocation(fSSODP->ownLoc,
- ((*fHandlePtr)->mmMsgHdr.MsgDest)), GetLNN());
- p->tag.isResident =
- fSSODP->tag.isResident = FALSE;
-
- /* Fill in ssodentry */
- ssodentry.tag = p->tag;
- ssodentry.ownOID = p->ownOID;
- ssodentry.ownLoc = fSSODP->ownLoc;
- ssodentry.processOID = p->processOID;
- ssodentry.oldSSPtr = p;
- ssodentry.oldReadyQLink = p->readyQLink;
- ssodentry.status = p->status;
- ssodentry.availStack = p->availStack;
- ssodentry.thisSegmentSize = p->segmentSize;
- ssodentry.regs = p->regs;
- ssodentry.resultBrand = p->resultBrand;
- ssodentry.rPtr = p->rPtr;
- ssodentry.invokePtr = p->invokePtr;
-
- LMPutData(fHandlePtr, &ssodentry, sizeof(TTMoveSSODEntry));
- LMPutData(fHandlePtr, p->regs.sp, sizeOfCut);
-
- }
-
- /**********************************************************************/
- /**********************************************************************/
- /* MoveProcessQueueToTTable */
- /**********************************************************************/
- /*ARGSUSED*/
- void MoveProcessQueueToTTable(fHandlePtr, fHeadSSPtr, fSentMap, fARSet)
- LMHandle *fHandlePtr;
- register SSPtr fHeadSSPtr;
- Map fSentMap;
- Set fARSet;
- /* This procedure moves the processes queue pointed to by fHeadSSPtr
- * into the TTable for transmission over the net.
- */
-
- {
- register SSPtr p;
- /*
- * Traverse the list and put the top AR of each process into the ARSet.
- * This ensures that the processes will be moved when the ARSet is
- * processed.
- */
- KMDTrace("Move", 4, "Moving Process Queue\n");
- p = fHeadSSPtr;
- if (NonNULL(p)) {
- do {
- p = p->readyQLink;
- KMDTrace("Move", 4, "\t%s in %s\n", PPPOID(p->processOID),
- PPSSPlace(p));
- KMDTrace("Move", 4, "Adding l = 0x%06x to ARSet\n", p->regs.l);
- Set_Insert(fARSet, (int) p->regs.l);
- } while (p != fHeadSSPtr);
- }
- }
-
- /**********************************************************************/
- /* MoveCondToTTable */
- /**********************************************************************/
- void MoveCondToTTable(fHandlePtr, fCondODP, fSentMap, fARSet)
- LMHandle *fHandlePtr;
- register CondODP fCondODP;
- Map fSentMap;
- Set fARSet;
- {
- KMDTrace("Move", 4, "Moving Condition 0x%06x\n", fCondODP);
-
- /* First move the process queue */
- MoveProcessQueueToTTable(fHandlePtr, fCondODP->waiting, fSentMap, fARSet);
-
- moveCondEntry.oldODP = (ODP) fCondODP;
- if (IsNULL(fCondODP->ownOID)) {
- OTInsert((ODP) fCondODP);
- }
- fCondODP->tag.seenHere = TRUE;
- fCondODP->tag.isResident = FALSE;
- fCondODP->ownLoc = NewLocation(fCondODP->ownLoc,
- (*fHandlePtr)->mmMsgHdr.MsgDest);
-
- moveCondEntry.tag = fCondODP->tag;
- moveCondEntry.ownOID = fCondODP->ownOID;
- moveCondEntry.ownLoc = fCondODP->ownLoc;
- moveCondEntry.theLock = fCondODP->theLock;
- moveCondEntry.theWaiting = fCondODP->waiting;
-
- KMDTrace("TT", 4,
- "AddTT: MoveCond(%s) 0x%06x monLock 0x%06x from %s, waiting 0x%06x\n",
- PPOID(fCondODP->ownOID), fCondODP, fCondODP->theLock,
- PPLoc(fCondODP->ownLoc), fCondODP->waiting);
-
- LMPutData(fHandlePtr, &moveCondEntry, sizeof(moveCondEntry));
-
- Map_Insert(fSentMap, (int) fCondODP, (int) RefMoved);
-
- DeActivateCond(fCondODP);
-
- }
-
- /**********************************************************************/
- /* MoveMonitorToTTable */
- /**********************************************************************/
- void MoveMonitorToTTable(fHandlePtr, fMonitorLockPtr, fSentMap, fARSet)
- LMHandle *fHandlePtr;
- register MonitorLockPtr fMonitorLockPtr;
- Map fSentMap;
- Set fARSet;
- /* Move the monitor and its conditions */
- {
- Set theSet;
- CondODP aCondODP;
-
- /*
- * First move the queue of waiting processes.
- */
- if (NonNULL(fMonitorLockPtr->waiting)) {
- MoveProcessQueueToTTable(fHandlePtr, fMonitorLockPtr->waiting,
- fSentMap, fARSet);
- }
-
- /* Conditions are handled specially. If the condition
- is within an object which is moving then the condition
- must also be moved. The set of waiting processes is
- represented in a queue originating in the CondOD.
- */
-
- theSet = (Set) Map_Lookup(condMap, (int) fMonitorLockPtr);
- if (IsNIL(theSet)) {
- KMDTrace("Move", 5, "No conditions tied to Mon Lock 0x%06x\n",
- fMonitorLockPtr);
- return;
- }
-
- /*
- * Go thru the set of conditions tied to the monitor and move them. The
- * monitorlock parts are moved automaticaly since they are contained in
- * the data area of the object.
- */
- Set_For(theSet, aCondODP)
- MoveCondToTTable(fHandlePtr, aCondODP, fSentMap, fARSet);
- Set_Next;
-
- /* Cleanup */
- Set_Destroy(theSet);
- Map_Delete(condMap, (int) fMonitorLockPtr);
- }
-
- /**********************************************************************/
- /* MoveInit */
- /**********************************************************************/
-
- void MoveInit()
- {
- KMDSetTrace(Move);
- KMDTrace("Move", 5, "MoveInit\n");
- KMDSetTrace(InvokeQueue);
- KMDTrace("InvokeQueue", 5, "InvokeQueue trace level 5\n");
-
- SetItemHandler(MoveITag, MoveItemHandler);
- }
-
- /* Copyright 1986 Eric Jul */
-